1import { H3 } from '@expo/html-elements'; 2import * as React from 'react'; 3import { 4 Platform, 5 ScrollView, 6 StyleSheet, 7 Image, 8 Text, 9 TouchableOpacity, 10 useWindowDimensions, 11 View, 12 RefreshControl, 13} from 'react-native'; 14 15import Button from '../components/Button'; 16import TitleSwitch from '../components/TitledSwitch'; 17 18export default function ScrollViewScreen() { 19 const [isHorizontal, setHorizontal] = React.useState(true); 20 const [isEnabled, setEnabled] = React.useState(true); 21 const [isRefreshing, setRefreshing] = React.useState(false); 22 const [removeClippedSubviews, setRemoveClippedSubviews] = React.useState(false); 23 const scrollView = React.useRef<ScrollView>(null); 24 const axis = isHorizontal ? 'x' : 'y'; 25 const { width } = useWindowDimensions(); 26 const isMobile = width <= 640; 27 const imageStyle = { 28 width, 29 height: width / 2, 30 }; 31 32 React.useEffect(() => { 33 let timeout: any; 34 if (isRefreshing) { 35 timeout = setTimeout(() => setRefreshing(false), 2000); 36 } 37 return () => { 38 clearTimeout(timeout); 39 }; 40 }, [isRefreshing]); 41 42 const onRefresh = () => { 43 setRefreshing(true); 44 }; 45 const items = React.useMemo(() => [...Array(20)].map((_, i) => `Item ${i}`), []); 46 return ( 47 <ScrollView 48 style={{ flex: 1 }} 49 removeClippedSubviews={removeClippedSubviews} 50 keyboardShouldPersistTaps="handled" 51 keyboardDismissMode="on-drag" 52 refreshControl={<RefreshControl refreshing={isRefreshing} onRefresh={onRefresh} />}> 53 <View style={{ flex: 1, paddingHorizontal: isMobile ? 8 : 12 }}> 54 <TitleSwitch 55 title="Remove Clipped Subviews" 56 value={removeClippedSubviews} 57 setValue={setRemoveClippedSubviews} 58 /> 59 <TitleSwitch title="Is Horizontal" value={isHorizontal} setValue={setHorizontal} /> 60 <TitleSwitch title="Is Enabled" value={isEnabled} setValue={setEnabled} /> 61 <ScrollView 62 onScroll={() => { 63 console.log('onScroll!'); 64 }} 65 scrollEventThrottle={200} 66 scrollEnabled={isEnabled} 67 nestedScrollEnabled 68 horizontal={isHorizontal} 69 ref={scrollView} 70 style={styles.scrollView}> 71 {items.map((title: string, index: number) => ( 72 <Item key={index}>{title}</Item> 73 ))} 74 </ScrollView> 75 <H3>Scroll to</H3> 76 <View style={{ flexDirection: 'row', justifyContent: 'space-between' }}> 77 <Button 78 title="Start" 79 style={{ flex: 1 }} 80 onPress={() => { 81 if (scrollView.current) { 82 scrollView.current.scrollTo({ [axis]: 0 }); 83 } 84 }} 85 /> 86 <Button 87 title="100px" 88 style={{ flex: 1 }} 89 onPress={() => { 90 if (scrollView.current) { 91 scrollView.current.scrollTo({ [axis]: 100 }); 92 } 93 }} 94 /> 95 <Button 96 title="End" 97 style={{ flex: 1 }} 98 onPress={() => { 99 if (scrollView.current) { 100 scrollView.current.scrollToEnd({ animated: true }); 101 } 102 }} 103 /> 104 </View> 105 <Button 106 title="Flash scroll indicators (web only)" 107 style={{ marginTop: 8 }} 108 disabled={Platform.OS !== 'web'} 109 onPress={() => { 110 if (scrollView.current) { 111 scrollView.current.flashScrollIndicators(); 112 } 113 }} 114 /> 115 </View> 116 <H3 style={{ marginHorizontal: 8 }}>Pagination</H3> 117 118 <ScrollView pagingEnabled directionalLockEnabled horizontal style={{ marginBottom: 8 }}> 119 <Image 120 source={require('../../assets/images/example1.jpg')} 121 style={imageStyle} 122 resizeMode="cover" 123 /> 124 <Image 125 source={require('../../assets/images/example2.jpg')} 126 style={imageStyle} 127 resizeMode="cover" 128 /> 129 <Image 130 source={require('../../assets/images/example3.jpg')} 131 style={imageStyle} 132 resizeMode="cover" 133 /> 134 </ScrollView> 135 </ScrollView> 136 ); 137} 138 139ScrollViewScreen.navigationOptions = { 140 title: 'ScrollView', 141}; 142 143function Item(props: { children: React.ReactNode }) { 144 return ( 145 <TouchableOpacity style={styles.item}> 146 <Text style={{ fontSize: 16 }}>{props.children}</Text> 147 </TouchableOpacity> 148 ); 149} 150 151const styles = StyleSheet.create({ 152 scrollView: { 153 backgroundColor: '#eeeeee', 154 height: 300, 155 flex: 1, 156 maxHeight: 300, 157 }, 158 text: { 159 fontSize: 16, 160 fontWeight: 'bold', 161 paddingVertical: 8, 162 }, 163 item: { 164 margin: 5, 165 padding: 8, 166 backgroundColor: '#cccccc', 167 borderRadius: 3, 168 minWidth: 96, 169 maxHeight: 96, 170 }, 171}); 172