javascript 我如何在react原生滚动条中设置滚动指示器的样式

368yc8dk  于 2023-02-15  发布在  Java
关注(0)|答案(4)|浏览(182)

我想添加一些风格到我的滚动指示器在垂直滚动条中使用的React原生。我想使滚动指示器更宽比默认大小,以便用户将清楚地看到滚动指示器。以及我想改变滚动指示器的颜色和其他一些东西。
我怎么能这样做呢?有没有可能在react native中的垂直滚动视图中设置滚动指示器?
也应该兼容任何平台

laik7k3q

laik7k3q1#

你应该在滚动时添加监听器,然后创建一个自定义视图,并转换它,因为scrollListener和不可见的滚动指示器这是你想要的简单实现:

class CustomScrollview extends PureComponent {
    state = {
        indicator: new Animated.Value(0),
        wholeHeight: 1,
        visibleHeight: 0
    }
    render() {
        const indicatorSize = this.state.wholeHeight > this.state.visibleHeight ?
            this.state.visibleHeight * this.state.visibleHeight / this.state.wholeHeight :
            this.state.visibleHeight

        const difference = this.state.visibleHeight > indicatorSize ? this.state.visibleHeight - indicatorSize : 1
        return (
            <View >
                <ScrollView
                    showsVerticalScrollIndicator={false}
                    onContentSizeChange={(width, height) => {
                        this.setState({ wholeHeight: height })
                    }}
                    onLayout={({ nativeEvent: { layout: { x, y, width, height } } }) => this.setState({ visibleHeight: height })}
                    scrollEventThrottle={16}
                    onScroll={Animated.event(
                        [{ nativeEvent: { contentOffset: { y: this.state.indicator } } }]
                    )}>

                </ScrollView >
                <View style={styles.indicatorWrapper} />
                <Animated.View style={[
                    styles.indicator, {
                        height: indicatorSize,
                        transform: [{
                            translateY: Animated.multiply(this.state.indicator, this.state.visibleHeight / this.state.wholeHeight).interpolate({
                                inputRange: [0, difference],
                                outputRange: [0, difference],
                                extrapolate: 'clamp'
                            })
                        }]
                    }]} />

            </View>
        )
    }
}

希望这能有所帮助!

yv5phkfx

yv5phkfx2#

您可以使用ScrollView的indicatorStyle prop 来改变颜色,但它只支持白色、黑色或默认三种颜色。您可以使用scrollIndicatorInsets prop 来设置指示器的插图。更多自定义样式,您可以使用react-native-scroll-indicator

mwecs4sa

mwecs4sa3#

您可以从ScrollView使用Animated from react-native、onLayout、onContentSizeChange和onScroll以及一些数学函数来完成此操作。
基本上,你可以比较ScrollView的可见高度和内容的实际大小(可见和隐藏),这样你就知道了滚动条的高度,然后你只需要在用户滚动时更新滚动条的位置。
请参见以下带有react钩子的代码示例:

const CustomScrollBarComponent = () => {
  const [completeScrollBarHeight, setCompleteScrollBarHeight] = useState(1);
  const [visibleScrollBarHeight, setVisibleScrollBarHeight] = useState(0);
  const scrollIndicator = useRef(new Animated.Value(0)).current;

  const scrollIndicatorSize =
    completeScrollBarHeight > visibleScrollBarHeight
      ? (visibleScrollBarHeight * visibleScrollBarHeight)
        / completeScrollBarHeight
      : visibleScrollBarHeight;

  const difference =
    visibleScrollBarHeight > scrollIndicatorSize
      ? visibleScrollBarHeight - scrollIndicatorSize
      : 1;

  const scrollIndicatorPosition = Animated.multiply(
    scrollIndicator,
    visibleScrollBarHeight / completeScrollBarHeight,
  ).interpolate({
    extrapolate: 'clamp',
    inputRange: [0, difference],
    outputRange: [0, difference],
  });

  const onContentSizeChange = (_, contentHeight) => 
    setCompleteScrollBarHeight(contentHeight);

  const onLayout = ({
    nativeEvent: {
      layout: { height },
    },
  }) => {
    setVisibleScrollBarHeight(height);
  };

  return (
    <View style={styles.scrollContainer}>
      <ScrollView
        contentContainerStyle={{ paddingRight: 14 }}
        onContentSizeChange={onContentSizeChange}
        onLayout={onLayout}
        onScroll={Animated.event(
          [{ nativeEvent: { contentOffset: { y: scrollIndicator } } }],
          { useNativeDriver: false },
        )}
        scrollEventThrottle={16}
        showsVerticalScrollIndicator={false}
        style={styles.scrollViewContainer}
      >
        {/* Your ScrollView content here */}
      </ScrollView>
      <View style={styles.customScrollBarBackground}>
        <Animated.View
          style={[
            styles.customScrollBar,
            {
              height: scrollIndicatorSize,
              transform: [{ translateY: scrollIndicatorPosition }],
            },
          ]}
        />
      </View>
    </View>
  );
};

样式:

const styles = StyleSheet.create({
  scrollContainer: {
    flexDirection: 'row',
    width: '100%',
  },
  scrollViewContainer: {
    width: '100%',
  },
  customScrollBar: {
    backgroundColor: '#ccc',
    borderRadius: 3,
    width: 6,
  },
  customScrollBarBackground: {
    backgroundColor: '#232323',
    borderRadius: 3,
    height: '100%',
    width: 6,
  },
});
pgccezyw

pgccezyw4#

免责声明:我扩展了Lord Pooria's answer并将其转换为npm package
Try it on Snack Expo

演示

这是一个从软件包文档复制的简单演示。

import * as React from 'react';
import {View, Text} from 'react-native';
import {ScrollViewIndicator} from '@fanchenbao/react-native-scroll-indicator';

const App = () => {
  return (
    <View
      style={{
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
      }}>
      <View
        style={{
          height: '30%',
          width: '80%',
          borderWidth: 1,
          borderColor: 'black',
        }}>
        <ScrollViewIndicator indStyle={{backgroundColor: 'green'}}>
          <View>
            <Text>
              Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam
              rhoncus nisl egestas, auctor mi pulvinar, aliquam metus. Nunc
              porttitor quam molestie tempor laoreet. Sed vitae ex vitae turpis
              convallis accumsan. Fusce consequat quis nisi sed lacinia. Nullam
              quis condimentum tellus. Donec ornare quam sit amet tempor
              imperdiet. Proin condimentum leo quis ipsum pretium ornare
              facilisis eget nunc. Pellentesque orci purus, pellentesque et nisl
              at, varius molestie nisi. Vestibulum ante ipsum primis in faucibus
              orci luctus et ultrices posuere cubilia curae; Nam ante nulla,
              sagittis vitae ante id, dignissim vestibulum ligula. Mauris
              iaculis nisi sed sapien finibus, sed pharetra risus rutrum. Cras
              laoreet mattis egestas. Pellentesque feugiat accumsan ultricies.
              Nullam viverra sapien nec tellus commodo aliquet. Integer faucibus
              quam sed nibh congue, at cursus risus vulputate. Morbi commodo
              mollis tempus.
            </Text>
          </View>
        </ScrollViewIndicator>
      </View>
    </View>
  );
};

export default App;

相关问题