item.value.scrollToOffset not working for me
See original GitHub issueScrollOffset does not sync fo each route, below is my code
import React, {useState, useEffect, useRef} from 'react';
import {
SafeAreaView,
StyleSheet,
View,
Text,
Dimensions,
Animated,
Image,
StatusBar
} from 'react-native';
import {TabView, TabBar, SceneMap} from 'react-native-tab-view';
import Icon from 'react-native-vector-icons/FontAwesome';
import IconF from 'react-native-vector-icons/Feather';
import ProfileFlatList from '../components/ProfileFlatList.js';
import { Thumbnail, Button, Tab, Tabs, TabHeading } from 'native-base';
const DATA = [
{image:require('../../assets/4.jpg'),isDraft:true,draftCount:'24',draftIcon:'inbox'},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/2.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/1.png'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/1.png'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/2.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false}
];
const DATA1 = [
{image:require('../../assets/4.jpg'),isDraft:true,draftCount:'24',draftIcon:'inbox'},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/2.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/1.png'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/1.png'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/2.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false}
];
const TabBarHeight = 48;
const HeaderHeight = 390;
const tab1ItemSize = (Dimensions.get('window').width - 30) / 3;
class TabScene extends React.Component {
render = () => {
const windowHeight = Dimensions.get('window').height;
const {
numCols,
data,
renderItem,
onGetRef,
scrollY,
onScrollEndDrag,
onMomentumScrollEnd,
onMomentumScrollBegin,
} = this.props;
return (
<Animated.FlatList
scrollToOverflowEnabled={true}
numColumns={numCols}
ref={onGetRef}
scrollEventThrottle={16}
onScroll={Animated.event(
[{nativeEvent: {contentOffset: {y: scrollY}}}],
{useNativeDriver: true},
)}
onMomentumScrollBegin={onMomentumScrollBegin}
onScrollEndDrag={onScrollEndDrag}
onMomentumScrollEnd={onMomentumScrollEnd}
ItemSeparatorComponent={() => <View style={{height: 10}} />}
ListHeaderComponent={() => <View style={{height: 10}} />}
contentContainerStyle={{
paddingTop: HeaderHeight + TabBarHeight,
paddingHorizontal: 10,
minHeight: windowHeight - TabBarHeight,
}}
showsHorizontalScrollIndicator={false}
data={data}
renderItem={renderItem}
showsVerticalScrollIndicator={false}
keyExtractor={(item, index) => index.toString()}
/>
);
};
}
const Profile = () => {
const [tabIndex, setIndex] = useState(0);
const [routes] = useState([
{key: 'tab1', title: 'Tab1'},
{key: 'tab2', title: 'Tab2'},
]);
const scrollY = useRef(new Animated.Value(0)).current;
let listRefArr = useRef([]);
let listOffset = useRef({});
let isListGliding = useRef(false);
useEffect(() => {
scrollY.addListener(({value}) => {
const curRoute = routes[tabIndex].key;
listOffset.current[curRoute] = value;
});
return () => {
scrollY.removeAllListeners();
};
}, [routes, tabIndex]);
const syncScrollOffset = () => {
const curRouteKey = routes[tabIndex].key;
listRefArr.current.forEach((item) => {
// sync value except current route
if (item.key !== curRouteKey) {
// if header has not yet been collapsed, scroll to current offset
if (scrollY._value < HeaderHeight && scrollY._value >= 0) {
if (item.value) {
item.value.scrollToOffset({
offset: scrollY._value,
animated: false,
});
// we should also update the offset here
listOffset.current[item.key] = scrollY._value;
}
// if header has been collapsed, scroll to HeaderHeight
} else if (scrollY._value >= HeaderHeight) {
if (listOffset.current[item.key] < HeaderHeight ||
listOffset.current[item.key] == null) {
if (item.value) {
item.value.scrollToOffset({
offset: HeaderHeight,
animated: false,
});
listOffset.current[item.key] = HeaderHeight;
}
}
}
}
});
};
const onMomentumScrollBegin = () => {
isListGliding.current = true;
};
const onMomentumScrollEnd = () => {
isListGliding.current = false;
syncScrollOffset();
};
const onScrollEndDrag = () => {
syncScrollOffset();
};
const renderHeader = () => {
const y = scrollY.interpolate({
inputRange: [0, HeaderHeight],
outputRange: [0, -HeaderHeight],
extrapolateRight: 'clamp',
});
return (
<Animated.View style={[styles.header, {transform: [{translateY: y}]}]}>
<View style={{width: "100%",}}>
<View style={{height:250,backgroundColor:'red'}}>
<Image source={require('../../assets/2.jpg')} style={styles.topBG}></Image>
<View style={styles.overlay} ></View>
</View>
<View style={{height:220, borderTopLeftRadius:30,borderTopRightRadius:30, marginTop:-40,backgroundColor:'#fff'}}>
<View style={{flex:0.3,flexDirection:'row',}}>
<View style={{marginTop:-40,marginLeft:50,
marginBottom:15,
shadowColor: '#000',
borderRadius:600,
shadowOffset: {
width: 0,
height: 1,
},
shadowOpacity: 0.2,
shadowRadius: 1.50,
elevation:10}}>
<Thumbnail large source={require('../../assets/4.jpg')} style={{borderWidth:3,borderColor:'white',}}/>
</View>
<View style={{marginLeft:15, marginTop:10}}>
<Text>@itsandysworld</Text>
<Text style={{color:'#c6c6c6'}}>ID: MT1989861</Text>
</View>
</View>
<View style={{flex:1,justifyContent:'space-around'}}>
<View style={{flexDirection:'row',justifyContent:'space-evenly',paddingHorizontal:40,marginTop:20}}>
<View style={{marginHorizontal:15,alignItems:'center',}}>
<Text>504</Text>
<Text style={{color:'#898b90'}}>Following</Text>
</View>
<View style={{borderRightColor:'#f1f1f1',borderRightWidth:2,height:20,marginTop:10}}></View>
<View style={{marginHorizontal:15,alignItems:'center',}}>
<Text>210.8K</Text>
<Text style={{color:'#898b90'}}>Fans</Text>
</View>
<View style={{borderRightColor:'#f1f1f1',borderRightWidth:2,height:20,marginTop:10}}></View>
<View style={{marginHorizontal:15,alignItems:'center',}}>
<Text>2.8m</Text>
<Text style={{color:'#898b90'}}>Hearts</Text>
</View>
</View>
<View style={{flexDirection:'row',justifyContent:'space-evenly',marginTop:5,paddingHorizontal:40, marginTop:40}}>
<Button bordered style={{width:130},styles.outlineBtn}>
<Text style={styles.outlineText}>Message</Text>
</Button>
<Button bordered style={styles.outlineBtn}>
<IconF name="user-check" color="#000"></IconF>
</Button>
<Button bordered style={styles.outlineBtn}>
<IconF name="video" color="#000"></IconF>
</Button>
</View>
<View style={{padding:10,alignItems:'center', marginTop:30, marginBottom:5}}>
<Text style={{color:'#969498'}}>#AndyFam</Text>
<Text style={{color:'#969498'}}>What's up AndyFam <Icon name='heart' color='#969498'></Icon> Don't forget to</Text>
<Text style={{color:'#969498'}}>subscribe to my YouTube</Text>
</View>
<View style={{borderTopColor:'#efefef',borderTopWidth:1,width:'90%',marginTop:25, marginLeft:20,}}></View>
</View>
</View>
</View>
</Animated.View>
);
};
const rednerTab1Item = ({item, index}) => {
return (
<View style={{ flex: 1,
marginLeft: index % 3 === 0 ? 0 : 10,
width: tab1ItemSize,
height: tab1ItemSize,
}}>
<Image style={{justifyContent: 'center',
alignItems: 'center',
width: '100%',
height: '100%',
borderRadius:8,
resizeMode: 'cover',}}
source={item.image } />
{item.isDraft &&
<View style={{
...StyleSheet.absoluteFillObject,
backgroundColor: 'rgba(0,0,0,0.6)',
borderRadius:8,
justifyContent: 'center',
alignItems: 'center',
}} >
<IconF name={item.draftIcon} color='#fff' size={20} style={{marginTop:35}}></IconF>
<Text style={{color:'#fff',marginTop:5,fontSize:12}}>Draft</Text>
<Text style={{color:'#fff',fontSize:12}}>{item.draftCount}</Text>
</View>
}
<View style={styles.bottomIcon}>
<View style={styles.bottomIconRow} >
<Text style={{color:item.textColor,fontSize:12}}><Icon name={item.viewIcon} color={item.iconColor} size={8}></Icon> {item.view}</Text>
<Text style={{color:item.textColor,fontSize:12}}><Icon name={item.heartIcon} color={item.iconColor} size={8}></Icon> {item.heart}</Text>
</View>
</View>
</View>
);
};
const renderLabel = ({route, focused}) => {
return (
<>
{route.key == 'tab1' &&
<Image height={20} width={20} style={{tintColor:focused ?"#fd0d3a" :"#c3c3c3"}} source={require('../../assets/profile_list_icon.png')}/>
}
{route.key == 'tab2' &&
<IconF size={20} name="heart" color={focused ?"#fd0d3a" :"#c3c3c3"} />
}
</>
);
};
const renderScene = ({route}) => {
const focused = route.key === routes[tabIndex].key;
let numCols;
let data;
let renderItem;
switch (route.key) {
case 'tab1':
numCols = 3;
data = DATA;
renderItem = rednerTab1Item;
break;
case 'tab2':
numCols = 3;
data = DATA1;
renderItem = rednerTab1Item;
break;
default:
return null;
}
return (
<TabScene
numCols={numCols}
data={data}
renderItem={renderItem}
scrollY={scrollY}
onMomentumScrollBegin={onMomentumScrollBegin}
onScrollEndDrag={onScrollEndDrag}
onMomentumScrollEnd={onMomentumScrollEnd}
onGetRef={(ref) => {
if (ref) {
const found = listRefArr.current.find((e) => e.key === route.key);
if (!found) {
listRefArr.current.push({
key: route.key,
value: ref,
});
}
}
}}
/>
);
};
const renderTabBar = (props) => {
const y = scrollY.interpolate({
inputRange: [0, HeaderHeight],
outputRange: [HeaderHeight, 0],
extrapolateRight: 'clamp',
});
return (
<Animated.View
style={{
top: 0,
zIndex: 1,
position: 'absolute',
transform: [{translateY: y}],
width: '100%',
}}>
<TabBar
{...props}
onTabPress={({route, preventDefault}) => {
if (isListGliding.current) {
preventDefault();
}
}}
style={styles.tab}
renderLabel={renderLabel}
indicatorStyle={styles.indicator}
/>
</Animated.View>
);
};
const renderTabView = () => {
return (
<TabView
onIndexChange={(index) => setIndex(index)}
navigationState={{index: tabIndex, routes}}
renderScene={renderScene}
renderTabBar={renderTabBar}
initialLayout={{
height: 0,
width: Dimensions.get('window').width,
}}
/>
);
};
return (
<>
<StatusBar
backgroundColor = "#fff"
barStyle = "light-content"
/>
<SafeAreaView style={{flex: 1, backgroundColor:'#fff'}}>
<View style={{flex: 1}}>
{renderTabView()}
{renderHeader()}
</View>
</SafeAreaView>
</>
);
};
const styles = StyleSheet.create({
header: {
top: 0,
height: 300,
width: '100%',
backgroundColor: '#40C4FF',
alignItems: 'center',
justifyContent: 'center',
position: 'absolute',
},
tab: {elevation: 0, shadowOpacity: 0, backgroundColor: '#fff'},
indicator: {backgroundColor: '#fd0d3a'},
container: {
flex: 1,
flexDirection: "column",
backgroundColor:'#fff'
},
row:{
flexDirection:"column",
margin:30,
},
overlay: {
...StyleSheet.absoluteFillObject,
backgroundColor: 'rgba(0,0,0,0.4)',
},
topBG:{
// flex: 1,
width:'100%',
resizeMode: 'cover',
},
outlineBtn:{
borderColor:'#c3c3c3',
paddingHorizontal:15,
borderRadius: 3,
alignItems:'center',
height:45,
// width:130
},
outlineText:{
color:'#000',
fontSize: 15,
textAlign: 'center',
padding:10,
alignSelf:'center',
backgroundColor: 'transparent'
},
tabBarUnderlineStyle:{
backgroundColor:'#fff',
height:2.5,
},
imageThumbnail: {
justifyContent: 'center',
alignItems: 'center',
height: 100,
},
bottomIconRow:{
flex:1,
flexDirection:'row',
justifyContent: 'space-evenly',
paddingHorizontal:0,
},
bottomIcon:{
//backgroundColor:'green',
position:'absolute',
bottom:0,
width:'100%',
marginBottom:8
}
});
export default Profile;
Issue Analytics
- State:
- Created 3 years ago
- Comments:18 (7 by maintainers)
Top Results From Across the Web
In react-native scrollToOffset in flat list is not working properly?
In flatlist scroll to offset is not working properly when the no of items are less than 3. If the no of items...
Read more >scrollToOffset not working ! : r/reactnative - Reddit
I have a flatList with a ref,when i call scrollToOffSet it doesnt work properly,it moves to the first item of the flatList ,what...
Read more >react native flatlist infinite loop - You.com | The AI Search ...
The FlatList (paging enabled, horizontal) has 3 to 7 items in the data array ... The problem is, I would like to update...
Read more >FlatList scrollToOffset bug - Expo Snack
FlatList scrollToOffset bug. Shows the broken behaviour of scrollToOffset function, which ignores the y value and always scrolls to top of the FlatList....
Read more >Writing custom strategy for Angular CDK virtual scroll
I'm a devoted Angular developer and a musician. I use one thing to help me not to starve while doing another and I...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
I have found a solution. Because ScrollView has no
scrollToOffset
function but onlyscrollTo
function, it is necessary to check the current component type run time if it is ScrollView.Hi @aroravinay4 Could you call
scrollToOffset
by getting the ref ofAnimatedKeyboardAwareScrollView
?and try:
scrollViewRef.current.scrollToOffset()
scrollToOffset is a props of
VirtualizedList
Maybe you should try scrollTo forreact-native-keyboard-aware-scroll-view