Pan Responder with transform not working in Android react native? - android

Problem:
In my react native app I have created an animation like tinder cards. It is working correctly in Ios but in Android Animated view which has panResponder and transform even does not render in the view . This is how I have organized my code.
const TinderCardAnimation = ({ theme, data, onHeartClick }) => {
const { width, height } = useWindowDimensions();
const [currentIndex, setCurrentIndex] = useState(0);
const pan = useRef(new Animated.ValueXY()).current;
const rotate = pan.x.interpolate({
inputRange: [-width / 2, 0, width / 2],
outputRange: ['-10deg', '0deg', '10deg'],
extrapolate: 'clamp'
})
const rotateAndTranslate = {
transform: [{
rotate: rotate
},
...pan.getTranslateTransform()
]
}
const likeOpacity = pan.x.interpolate({
inputRange: [-width / 2, 0, width / 2],
outputRange: [0, 0, 1],
extrapolate: 'clamp'
})
const nopeOpacity = pan.x.interpolate({
inputRange: [-width / 2, 0, width / 2],
outputRange: [1, 0, 0],
extrapolate: 'clamp'
})
const panResponder = useRef(
PanResponder.create({
onMoveShouldSetPanResponder: () => true,
onStartShouldSetPanResponder: (evt, gestureState) => true,
onStartShouldSetPanResponderCapture: (evt, gestureState) =>
true,
onMoveShouldSetPanResponderCapture: (evt, gestureState) =>
true,
onPanResponderTerminationRequest: (evt, gestureState) =>
true,
onPanResponderGrant: () => {
pan.setOffset({
x: pan.x._value,
y: pan.y._value
});
},
onPanResponderMove: (evt, gestureState) => {
pan.setValue({
x: gestureState.dx,
y: gestureState.dy
})
},
onPanResponderRelease: () => {
pan.flattenOffset();
},
onShouldBlockNativeResponder: (evt, gestureState) => {
// Returns whether this component should block native components from becoming the JS
// responder. Returns true by default. Is currently only supported on android.
return true;
}
})
).current;
return <View style={{ backgroundColor: '#ffffff' }}>{data?.map((item, index) => {
if (index < currentIndex) {
return null
} else if (index == currentIndex) {
return (<Animated.View {...panResponder.panHandlers} key={index} style={[rotateAndTranslate, { height: height / 5, width: width, padding: 10, position: 'absolute' }]}>
<Animated.View
style={{
opacity: likeOpacity,
transform: [{ rotate: "-30deg" }],
position: "absolute",
top: 50,
left: 40,
zIndex: 1000
}}
>
<TouchableOpacity >
<Image style={{ marginTop: height / 4 }} source={require("_assets/images/XCircleb.png")} />
</TouchableOpacity>
</Animated.View>
<Animated.View
style={{
opacity: nopeOpacity,
transform: [{ rotate: "30deg" }],
position: "absolute",
top: 50,
right: 40,
zIndex: 1000
}}
>
<TouchableOpacity onPress={() => onHeartClick(item?.id)}>
<Image style={{ marginTop: height / 4 }} source={require("_assets/images/HCircleb.png")} />
</TouchableOpacity>
</Animated.View>
<ProfileCard key={index} profile={item} />
</Animated.View>)
} else {
return (<Animated.View key={index} style={{ height: height / 5, width: width, padding: 10, position: 'absolute' }}>
<ProfileCard key={index} profile={item} />
</Animated.View>)
}
}).reverse()}
</View >
}
export default withTheme(TinderCardAnimation);
I tried a lot to make it work in Android. But I was unable to do so. Can someone help me to solve this issue? Thank you

Related

ReactNative animation is not working after the api call

here is my code.
const actionButtonsAnimated = new Animated.Value(0);
const animated = new Animated.Value(255);
const animateTrendingCardSheet = () => {
Animated.timing(animated, {
toValue: 0,
duration: 1500,
useNativeDriver: true,
}).start();
Animated.timing(actionButtonsAnimated, {
toValue: -180,
duration: 1000,
useNativeDriver: true,
}).start();
};
<Animated.View
style={[
{
transform: [{ translateY: actionButtonsAnimated }],
},
]}
>
<MainActionButtons />
</Animated.View>
<Animated.View
style={[
{
transform: [{ translateY: animated }],
width: "100%",
position: "absolute",
bottom: 0,
},
]}
>
<View style={styles.trendingCards}>
<Text h5 center color={colors.trendingText}>
Trending in your area...
</Text>
<View style={styles.flatlistWrapper}>
<FlatList
horizontal={true}
data={trendingCards}
renderItem={({ item }) => <TrendingCardComponent card={item} />}
/>
</View>
</View>
</Animated.View>
so if i call the animateTrendingCardSheet function inside useEffect like this.
useEffect(() => {
animateTrendingCardSheet()
}, [])
it works as expected but once i put it in a condition that it should be called after the API call has been finished it does not work at all if i again save the file it hot reload animation works
useEffect(() => {
if (loadTrendingCard) {
animateTrendingCardSheet();
}
}, [loadTrendingCard]);
Your issue is that after the first call to animateTrendingCardSheet the toValue that you are animating to is the current value of your Animated variables; so it looks like nothing is happening. You can counteract this by resetting your animation variables before calling your animation function:
import * as React from 'react';
import {
Text,
View,
StyleSheet,
Animated,
TouchableOpacity,
FlatList,
Button
} from 'react-native';
import Constants from 'expo-constants';
const MainActionButtons = () => {
return (
<View
style={{
flexDirection: 'row',
width: '100%',
justifyContent: 'space-between',
}}>
<TouchableOpacity>Btn 1</TouchableOpacity>
<TouchableOpacity>Btn 2</TouchableOpacity>
<TouchableOpacity>Btn 3</TouchableOpacity>
<TouchableOpacity>Btn 4</TouchableOpacity>
</View>
);
};
const TrendingCardComponent = ({ card }) => {
return (
<View style={{ width: '100%' }}>
<Text>{card.title}</Text>
<Text>{card.message}</Text>
</View>
);
};
const trendingCards = [
{ title: 'A Cool Card', message: 'A cool message' },
{ title: 'Card 1', message: 'A cool message' },
{ title: 'A Cool Card', message: 'A cool message' },
{ title: 'A Cool Card', message: 'A cool message' },
];
const initialActionButton = 0;
const initialAnimated = 255;
export default function App() {
const actionButtonsAnimated = new Animated.Value(initialActionButton);
const animated = new Animated.Value(initialAnimated);
const opacity = new Animated.Value(1)
const onApiCall = ()=>{
// set opacity to 0
Animated.timing(opacity,{toValue:0,duration:500}).start(()=>{
// when view is invisible do resets
animated.setValue(initialAnimated)
actionButtonsAnimated.setValue(initialActionButton)
Animated.timing(opacity,{toValue:1,duration:500}).start()
animateTrendingCardSheet()
})
}
const animateTrendingCardSheet = () => {
Animated.timing(animated, {
toValue: 0,
duration: 1500,
useNativeDriver: true,
}).start();
Animated.timing(actionButtonsAnimated, {
toValue: -180 ,
duration: 1000,
useNativeDriver: true,
}).start();
};
// React.useEffect(() => {
// animateTrendingCardSheet();
// }, []);
return (
<View style={styles.container}>
<Button title="Simulate API call" onPress={onApiCall}/>
<Animated.View
style={[
{
transform: [{ translateY: actionButtonsAnimated }],
opacity
},
]}>
<MainActionButtons />
</Animated.View>
<Animated.View
style={[
{
transform: [{ translateY: animated }],
width: '100%',
position: 'absolute',
bottom: 0,
opacity
},
]}>
<View style={styles.trendingCards}>
<Text>Trending in your area...</Text>
<View style={styles.flatlistWrapper}>
<FlatList
style={{ flex: 1 }}
horizontal={true}
data={trendingCards}
renderItem={({ item }) => <TrendingCardComponent card={item} />}
/>
</View>
</View>
</Animated.View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
flatlistWrapper: {
width: '100%',
height: 200,
},
});
Demo
The above answer is good but it does not solve my problem, its all due to a stupid mistake, the issue was i was setting the state before calling the animation call function, as the state changes and it interfere the animation i had to use useRef like this.
const actionButtonsAnimated = useRef(new Animated.Value(initialActionButton)).current;
const animated = useRef(new Animated.Value(initialAnimated)).current;
it reference the state and animation works as expected.

How to go from top to bottom of a ScrollView in React Native?

I'm in a React Native project that the client wants the product image scrolls from top to bottom vice versa in a modal, how can I achive this?
I already know how to solve this...
I had to create a counter that increase or decrease Y axis of ScrollView every 0.5 seconds and checking if reached the top or bottom.
In the modal component file:
import React, { useState, useEffect } from 'react';
import { StyleSheet, Modal, ScrollView, View, Image, NativeSyntheticEvent, NativeScrollEvent } from 'react-native';
import { Feather } from '#expo/vector-icons';
const ImageModal: React.FC<{ product: ProductType }> = ({ product }) => {
const [ axisY, setAxisY ] = useState<number>(0); // State that is used to know the current Y axis of ScrollView
const [ scrollToTop, setScrollToTop ] = useState<boolean>(false); // State that is used to checks if should go to top or bottom
// Handler that checks if ScrollView is scrolling to top or bottom
const handleScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => {
// HELP: https://newbedev.com/detect-scrollview-has-reached-the-end
const { layoutMeasurement, contentOffset, contentSize } = event.nativeEvent; // Get scroll event properties
// If scrolling to top
if (scrollToTop) {
const isNearTop = contentOffset.y != 0; // Checks if Y axis reached the top of ScrollView
setScrollToTop(isNearTop); // Change the state value to FALSE, making ScrollView goes to bottom
} else {
const isNearBottom = layoutMeasurement.height + contentOffset.y >= contentSize.height; // Checks if Y axis reached the bottom of ScrollView
setScrollToTop(isNearBottom); // Change the state value to TRUE, making ScrollView goes to top
}
}
// Increase or decrease current Y axis every 0.5 seconds
useEffect(() => {
const timer = setInterval(() => {
setAxisY(prev => !scrollToTop ? prev + 1.5 : prev - 1.5);
}, 50);
return () => clearInterval(timer);
}, [scrollToTop]);
return (
<Modal
visible={ true }
transparent={ true }
statusBarTranslucent={ true }
animationType="fade"
>
<View style={ styles.container }>
<View style={ styles.box }>
<ScrollView
overScrollMode="never"
style={ styles.scroll }
scrollEnabled={ false }
showsVerticalScrollIndicator={ false }
contentOffset={{ x: 0, y: axisY }}
onScroll={ handleScroll }
>
<View style={ styles.imageBox }>
<Image source={{ uri: product.image_url }} style={ styles.image } />
</View>
</ScrollView>
<View>
<Text>Some random text!</Text>
</View>
</View>
<TouchableOpacity style={ styles.closeButton } onPress={ onClose }>
<Feather name="x" size={ 30 } color="#fff" />
</TouchableOpacity>
</View>
</Modal>
);
}
// Main Styles
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'row',
backgroundColor: 'rgba(0, 0, 0, 0.5)',
padding: 20
},
closeButton: {
width: 60,
height: 60,
borderWidth: 2,
borderRadius: 12,
marginLeft: 20,
borderColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#58585a'
},
box: {
backgroundColor: '#fff',
width: '80%',
borderRadius: 10,
flexDirection: 'column'
},
scroll: {
width: '100%',
height: '80%',
borderBottomWidth: 1,
borderColor: '#58585a'
},
imageBox: {
width: '100%',
height: 600,
},
image: {
width: '100%',
height: '100%',
resizeMode: 'cover',
borderTopLeftRadius: 10,
borderTopRightRadius: 10
}
});
export default ImageModal;

How to use the helper function provided by a library?

I am using react-native-animated-charts to render a chart. However, I am having difficulty reading x, and y values of the moveable chart dot. The documentation mentions that useChartData helper function gives access to this information. However, I am unsure how to use (or even where to use or initialize this function).
EDIT: I have added the code below
import React, {useEffect, useState, useRef} from 'react';
import {Text, Dimensions, View, TouchableHighlight, StyleSheet} from 'react-native';
import {
ChartDot,
ChartPath,
ChartPathProvider,
ChartYLabel,
ChartXLabel,
useChartData,
monotoneCubicInterpolation,
} from '#rainbow-me/animated-charts';
import {runOnJS} from 'react-native-reanimated';
import Card2View from '..//Card2View/Card2View';
import styles from './styles';
export const {width: SIZE, height} = Dimensions.get('window');
const TABLE_ITEM_OFFSET = 10;
const TABLE_ITEM_MARGIN = TABLE_ITEM_OFFSET * 2;
const SCREEN_WIDTH = SIZE < height ? SIZE : height;
export const data = [
{x: 1453075200, y: 1.47},
{x: 1453161600, y: 1.37},
{x: 1453248000, y: 1.53},
{x: 1453334400, y: 1.54},
{x: 1453420800, y: 1.52},
{x: 1453507200, y: 2.03},
{x: 1453593600, y: 2.1},
{x: 1453680000, y: 2.5},
{x: 1453766400, y: 2.3},
{x: 1453852800, y: 2.42},
{x: 1453939200, y: 2.55},
{x: 1454025600, y: 2.41},
{x: 1454112000, y: 2.43},
{x: 1454198400, y: 2.2},
];
const points = monotoneCubicInterpolation({data, range: 40});
const LineChartView1 = ({priceData}) => {
const [activeChart, setActiveChart] = useState(0)
const lineChartTables = ['1D', '1W', '1M', '3M', '1Y', 'ALL'];
const output = useChartData()
console.log(output);
const getX = value => {
'worklet';
// console.log(runOnJS(useChartData("state")));
if (value === '') {
return '';
}
return `$ ${value.toLocaleString('en-US', {
currency: 'USD',
})}`;
};
const getY = value => {
'worklet';
// console.log(runOnJS(useChartData("state")));
if (value === '') {
return '';
}
const date = new Date(Number(value * 1000));
const s = date.getSeconds();
const m = date.getMinutes();
const h = date.getHours();
const d = date.getDate();
const n = date.getMonth();
const y = date.getFullYear();
return `${y}-${n}-${d} ${h}:${m}:${s}`;
};
renderTable = (item, index) => (
<TouchableHighlight
onPress={() => setActiveChart(index)}
underlayColor="rgba(73,182,77,1,0.9)"
key={index}
style={
activeChart == index
? {
justifyContent: 'center',
backgroundColor: '#617180',
borderRadius: 5,
flex: 1,
alignItems: 'center',
margin: TABLE_ITEM_OFFSET,
width:
(SCREEN_WIDTH - TABLE_ITEM_MARGIN) / lineChartTables.length -
TABLE_ITEM_OFFSET,
height:
(SCREEN_WIDTH - TABLE_ITEM_MARGIN) / lineChartTables.length -
TABLE_ITEM_OFFSET,
maxWidth: 50,
maxHeight: 50
}
: {
justifyContent: 'center',
backgroundColor: 'white',
borderRadius: 5,
flex: 1,
alignItems: 'center',
margin: TABLE_ITEM_OFFSET,
width:
(SCREEN_WIDTH - TABLE_ITEM_MARGIN) / lineChartTables.length -
TABLE_ITEM_OFFSET,
height:
(SCREEN_WIDTH - TABLE_ITEM_MARGIN) / lineChartTables.length -
TABLE_ITEM_OFFSET,
maxWidth: 50,
maxHeight: 50
}
}
>
<Text style={activeChart == index ? chart.activeChartTxt : chart.chartTxt}>
{item}
</Text>
</TouchableHighlight>
);
return(
<View>
<Card2View item={{title:priceData.symbol, text:priceData.lastUpdatedPrice, money:`Rs. ${priceData.lastUpdatedPrice}`, procent:`${(priceData.percentageChange).toFixed(2)}`}} />
<View
style={{backgroundColor: 'white'}}>
<ChartPathProvider
data={{
points,
smoothingStrategy: 'bezier',
}}
>
<ChartPath height={SIZE / 2} stroke="black" strokeWidth="2" selectedOpacity="0.3" width={SIZE} />
<ChartDot
style={{
backgroundColor: 'black',
}}
size={15}
/>
{/* <ChartYLabel format={getX} style={{backgroundColor: 'white', color: 'black'}}/>
<ChartXLabel format={getY} style={{backgroundColor: 'white', color: 'black'}}/> */}
</ChartPathProvider>
<View style={{ flexDirection: 'row', justifyContent: 'space-around', flex: 1 }}>
{lineChartTables.map((data, index) => renderTable(data, index))}
</View>
</View>
</View>
)
}
export default LineChartView1;
const chart = StyleSheet.create({
chartTxt: {
fontSize: 14,
color: 'black'
},
activeChartTxt: {
fontSize: 14,
color: 'white',
fontWeight: 'bold'
}
});
You need to call the hook inside the ChartPathProvider. Example:
const ChildComponent = () => {
const values = useChartData();
return <Text>{values.greatestX}</Text>
}
const ParentComponent = ({ points }) => (
<ChartPathProvider
data={{
points,
smoothingStrategy: 'bezier',
}}
>
{/* other chart components */}
<ChildComponent />
</ChartPathProvider>
)
In your example, you are calling the hook before you define the provider (i.e. before the return statement).
in addition to the answer provided above by #Paul Kuhle
you can use the following to be able to access chartData
import React, {useContext} from 'react';
import ChartContext from '#rainbow-me/animated-charts/src/helpers/ChartContext';
const {positionX, positionY, dotScale, providedData, greatestY, layoutSize} = useContext(ChartContext);
and you may want to use useEffect to detect changes in the chart, let me know if that helps

How to drew a line between two points in react native?

I'm working on React Native.
Actually I want to draw a line between two points in react native.
The point is where I start touch and where I release touch.
I'm doing this using penResponder.
Using penResponder I get those point. Where i start touch and where I release touch.
Here is my code:
import React, {Component} from 'react';
import {
StyleSheet,
View,
Platform,
Text,
PanResponder,
Image,
} from 'react-native';
export default class App extends Component {
constructor() {
super();
//initialize state
this.panResponder;
this.state = {
locationX: 0,
locationY: 0,
locationSX: 0,
locationSY: 0,
};
//panResponder initialization
this.panResponder = PanResponder.create({
onStartShouldSetPanResponder: (event, gestureState) => true,
onStartShouldSetPanResponderCapture: (event, gestureState) => {
this.setState({
locationX: event.nativeEvent.locationX.toFixed(2),
locationY: event.nativeEvent.locationY.toFixed(2),
});
},
onMoveShouldSetPanResponder: (event, gestureState) => false,
onMoveShouldSetPanResponderCapture: (event, gestureState) => false,
onPanResponderGrant: (event, gestureState) => false,
onPanResponderMove: (event, gestureState) => {},
onPanResponderRelease: (event, gestureState) => {
this.setState({
locationSX: event.nativeEvent.locationX.toFixed(2),
locationSY: event.nativeEvent.locationY.toFixed(2),
});
},
});
this.setState({
locationX: 0,
locationY: 0,
locationSX: 0,
locationSY: 0,
});
}
render() {
return (
<View style={styles.MainContainer}>
<View style={styles.childView}>
<View
style={[
{
height: 22,
width: 22,
marginTop: 5,
position: 'absolute',
borderRadius: 14,
backgroundColor: '#afeeee',
},
{
top: parseFloat(this.state.locationY - 5),
left: parseFloat(this.state.locationX - 15),
},
]}
/>
<View
style={[
{
height: 22,
width: 22,
marginTop: 5,
position: 'absolute',
borderRadius: 14,
backgroundColor: '#afeeee',
},
{
top: parseFloat(this.state.locationSY - 2),
left: parseFloat(this.state.locationSX - 11),
},
]}
/>
<View
style={{flex: 1, backgroundColor: 'transparent'}}
{...this.panResponder.panHandlers}
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
MainContainer: {
flex: 1,
},
childView: {
flex: 1,
overflow: 'hidden',
},
point: {
height: 22,
width: 22,
marginTop: 5,
position: 'absolute',
borderRadius: 14,
backgroundColor: '#afeeee',
},
});
But how to draw line between the two points?
Actually I want this:
Please help!
Thanks in advance.
You can use svg (https://github.com/react-native-community/react-native-svg) to do this. I recommend you to put your PanResponder on top of your svg to handle touches.
Svg example:
<Svg height={windowHeight} width={windowWidth}>
<Line x1={startTouch.x} y1={startTouch.y} x2={endTouch.x} y2={endTouch.y} stroke="red" strokeWidth="2" />
</Svg>

How to use FlatList with sticky headers in animated.ScrollView

I use animated.ScrollView and animated.View to move header and tabs to the top of the screen by animation when the user scrolls up the page.
everything is ok until here.
I want to use FlatList With sticky headers in one of the tabs.
when I use animated.ScrollView, sticky headers of FlatList not work!
and when in replace animated.ScrollView to animated.View this resolve but header and tabs cant move to top of the screen!
my code:
render() {
// Because of content inset the scroll value will be negative on iOS so bring
// it back to 0.
const scrollY = Animated.add(
this.state.scrollY,
Platform.OS === 'ios' ? HEADER_MAX_HEIGHT : 0,
);
const headerTranslate = scrollY.interpolate({
inputRange: [0, HEADER_SCROLL_DISTANCE],
outputRange: [0, -HEADER_SCROLL_DISTANCE],
extrapolate: 'clamp',
});
const backBtn = scrollY.interpolate({
inputRange: [0,HEADER_SCROLL_DISTANCE / 4, HEADER_SCROLL_DISTANCE / 2, HEADER_SCROLL_DISTANCE],
outputRange: [0, 0 , 0, 1],
extrapolate: 'clamp',
});
const imageOpacity = scrollY.interpolate({
inputRange: [0, HEADER_SCROLL_DISTANCE / 2, HEADER_SCROLL_DISTANCE],
outputRange: [1, 1, 0],
extrapolate: 'clamp',
});
const imageTranslate = scrollY.interpolate({
inputRange: [0, HEADER_SCROLL_DISTANCE],
outputRange: [0, 100],
extrapolate: 'clamp',
});
const titleScale = scrollY.interpolate({
inputRange: [0, HEADER_SCROLL_DISTANCE / 2, HEADER_SCROLL_DISTANCE],
outputRange: [1, 1, 0.6],
extrapolate: 'clamp',
});
const titleTranslate = scrollY.interpolate({
inputRange: [0, HEADER_SCROLL_DISTANCE / 2, HEADER_SCROLL_DISTANCE],
outputRange: [0, 0, -8],
extrapolate: 'clamp',
});
const tabY = scrollY.interpolate({
inputRange: [0, HEADER_SCROLL_DISTANCE, HEADER_SCROLL_DISTANCE + 1],
outputRange: [0, 0, 1]});
return (
<View style={styles.fill}>
<StatusBar
barStyle="light-content"
backgroundColor="#333f5b"
/>
<Animated.ScrollView
style={styles.fill}
scrollEventThrottle={1}
onScroll={Animated.event(
[{ nativeEvent: { contentOffset: { y: this.state.scrollY } } }],
{ useNativeDriver: true },
)}
refreshControl={
<RefreshControl
refreshing={this.state.refreshing}
onRefresh={() => {
this.get_detail();
this.get_Comment(this.state.type,this.state.id);
this.setState({ refreshing: true,
loadingComment:true,
});
}}
// Android offset for RefreshControl
progressViewOffset={HEADER_MAX_HEIGHT}
/>
}
// iOS offset for RefreshControl
contentInset={{
top: HEADER_MAX_HEIGHT,
}}
contentOffset={{
y: -HEADER_MAX_HEIGHT,
}}
>
<Tabs renderTabBar={(props) => <Animated.View
style={[{
transform: [{translateY: tabY}],
zIndex: 1,
width: "100%",
backgroundColor: COLOR,
marginTop:HEADER_MAX_HEIGHT ,
}, Platform.OS === "ios" ? {paddingTop: 20} : null]}>
<ScrollableTab {...props} underlineStyle={{backgroundColor: "white"}}/>
</Animated.View>
}>
<Tab heading="MainTab" {...TAB_PROPS}>
{this._renderMainTab()}
</Tab>
<Tab heading="ListTab" {...TAB_PROPS}>
{this._renderListTab()}
</Tab>
<Tab heading="CommentTab" {...TAB_PROPS}>
{this._renderCommentTab()}
</Tab>
</Tabs>
</Animated.ScrollView>
<Animated.View
pointerEvents="none"
style={[
styles.header,
{ transform: [{ translateY: headerTranslate }] },
]}
>
<Animated.Image
style={[
styles.backgroundImage,
{
opacity: imageOpacity,
transform: [{ translateY: imageTranslate }],
},
]}
source={{uri:this.state.top_image}}
/>
</Animated.View>
<Animated.View
style={[
styles.bar,
{
transform: [
{ scale: titleScale },
{ translateY: titleTranslate },
],
},
]}
>
<Text style={styles.title}>{this.state.title}</Text>
</Animated.View>
<Animated.View
style={[
styles.backBtn,
{
opacity: backBtn,
},
]}
>
<Button transparent onPress={this.back}>
<Icon reverse type="MaterialIcons" name="arrow-back" style={{transform: [{scaleX: I18nManager.isRTL ? -1 : 1}],color:"#fff"}}/>
</Button>
</Animated.View>
</View>);}}
and FlatList is in _renderListTab() :
<FlatList style={{backgroundColor: '#eee'}}
data={this.props.data}
renderItem={this.renderItem}
keyExtractor={item => item.title+item.id}
stickyHeaderIndices={this.props.sticky}/>
how can fix it?!
are there any way to use FlatList with sticky headers in tabs that in animated.ScrollView?

Categories

Resources