我想在我的滚动指示器中添加一些样式用于反向原生的垂直滚动条。我想让滚动指示器比默认大小更宽,以便用户清楚地看到滚动指示器。我想改变滚动指示器中的颜色和其他一些东西。
我该怎么办?是否有可能在垂直滚动视图中对滚动指示器进行反应本机..
也应该在任何平台兼容
答案 0 :(得分:3)
您可以使用ScrollView的indicatorStyle
道具来改变颜色,但它只支持三种颜色白色,黑色或默认颜色。您可以使用scrollIndicatorInsets
道具设置指标的插图。要获得更多自定义样式,您可以使用react-native-scroll-indicator。
答案 1 :(得分:2)
您应该在滚动条上添加侦听器,然后创建一个自定义视图,并通过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>
)
}
}
希望获得帮助!
答案 2 :(得分:0)
您可以使用 ScrollView 中的 Animated from react-native、onLayout、onContentSizeChange 和 onScroll 以及一些数学方法来完成此操作。
基本上,您可以将 ScrollView 的可见高度与内容的实际完整大小(可见和隐藏)进行比较,从而知道滚动条的高度。然后你只需要在用户滚动时更新那个栏的位置。
请参阅以下带有反应钩子的代码示例:
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.petItemListContainer}
>
{/* 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%',
},
petItemListContainer: {
width: '100%',
},
customScrollBar: {
backgroundColor: '#ccc',
borderRadius: 3,
width: 6,
},
customScrollBarBackground: {
backgroundColor: '#232323',
borderRadius: 3,
height: '100%',
width: 6,
},
});