首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >以绝对位置Animated.View为中心的视图在ScrollView移位位置内

以绝对位置Animated.View为中心的视图在ScrollView移位位置内
EN

Stack Overflow用户
提问于 2022-11-24 17:29:26
回答 1查看 28关注 0票数 0

呈现TabList的代码:

代码语言:javascript
运行
复制
import React, { Children, useEffect } from 'react';
import { LayoutChangeEvent, View } from 'react-native';
import {
  ScrollView,
  TouchableWithoutFeedback,
} from 'react-native-gesture-handler';
import Animated, {
  Easing,
  useAnimatedStyle,
  useSharedValue,
  withTiming,
} from 'react-native-reanimated';

import { isValidChild } from '@utils';

import { useTabIndex } from '../tab-context';

import { useStyle } from './tab-list.styles';
import { TabListProps } from './tab-list.type';

const animConfig = {
  duration: 200,
  easing: Easing.bezier(0.25, 0.1, 0.25, 1),
};

const TabList: React.FC<TabListProps> = props => {
  const styles = useStyle();
  const { children, onChange } = props;
  const selectedTabIndex = useTabIndex();
  const animatedTabIndicatorPosition = useSharedValue(0);

  // Save layout of the container
  const [containerLayout, setContainerLayout] = React.useState({
    x: 0,
    y: 0,
    width: 0,
    height: 0,
  });

  const onContainerLayout = (event: LayoutChangeEvent) => {
    const { x, y, width, height } = event.nativeEvent.layout;
    setContainerLayout({ x, y, width, height });
  };

  // get children length
  const childrenLength = Children.count(children);
  const tabWidth =
    childrenLength > 3
      ? containerLayout.width / 3
      : containerLayout.width / childrenLength;

  const renderChildren = () => {
    // Render only children of component type TabList
    return Children.map(children, child => {
      // Check if child is a valid React element and has type TabList
      if (isValidChild(child, 'Tab')) {
        return (
          <TouchableWithoutFeedback
            containerStyle={{ width: tabWidth }}
            onPress={() => onChange((child as JSX.Element)?.props.tabIndex)}
          >
            {child}
          </TouchableWithoutFeedback>
        );
      }

      // Throw error if child is not a TabList
      throw new Error('TabList component can only have children of type Tab');
    });
  };

  useEffect(() => {
    animatedTabIndicatorPosition.value = selectedTabIndex * tabWidth;
  }, [selectedTabIndex]);

  const indicatorAnimatedStyle = useAnimatedStyle(() => {
    return {
      width: tabWidth,
      transform: [
        {
          translateX: withTiming(
            animatedTabIndicatorPosition.value,
            animConfig,
          ),
        },
      ],
    };
  }, []);

  return (
    <View onLayout={onContainerLayout} style={styles.container}>
      <ScrollView
        horizontal
        showsHorizontalScrollIndicator={false}
        testID="TestID__component-TabList"
      >
        <Animated.View
          style={[styles.indicatorContainer, indicatorAnimatedStyle]}
        >
          <View
            style={[
              styles.indicator,
              {
                width: tabWidth - 4,
              },
            ]}
          />
        </Animated.View>
        {renderChildren()}
      </ScrollView>
    </View>
  );
};

export default TabList;

组件元素的样式:

代码语言:javascript
运行
复制
import { createUseStyle } from '@theme';

// createUseStyle basically returns (fn) => useStyle(fn)
export const useStyle = createUseStyle(theme => ({
  container: {
    position: 'relative',
    flexGrow: 1,
    backgroundColor: theme.palette.accents.color8,
    height: 32,
    borderRadius: theme.shape.borderRadius(4.5),
  },

  indicatorContainer: {
    position: 'absolute',
    height: 32,
    justifyContent: 'center',
    alignItems: 'center',
  },

  indicator: {
    height: 28,
    backgroundColor: theme.palette.background.main,
    borderRadius: theme.shape.borderRadius(4),
  },
}));

我使用的反应-本机-恢复动画选项卡指示符。我注意到的是,在应用程序重新加载时,初始选项卡指示符的位置一直在变化,如我所附的GIF所示。有时,它被放置在它应该在的位置,有时,一半的框隐藏在滚动视图容器后面。当我将alignItems: centerAnimated.View中移除时,一切都如愿以偿。

我很困惑为什么这个职位会因为align-items而不断变化

EN

回答 1

Stack Overflow用户

发布于 2022-11-24 18:39:59

编辑:忽略下面的行为,行为不是由于热重新加载!如果其他人有同样的误解,我就不谈了。

热重新加载是不可靠的重新动画-有在本机线程上的值,不会被刷新。这对最终的应用程序没有影响。

要测试它是否真的工作,只需摇一下设备/sim,然后在您进行更改后点击Reload。这足以清除任何粘性值。如果您的组件仍然没有完成您想要的操作,那么您可以有信心编辑它,并确保它看起来是正确的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74564445

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档