Есть ли способ изменить позицию stlyes: 'relative' в position: 'absolute' в зависимости от значения прокрутки Y в Animated.ScrollView React-Native
У меня есть анимированный заголовок, который становится меньше, а непрозрачность увеличивается при прокрутке вниз.. Под этим есть панель фильтра, которая должна оставаться чуть ниже анимированного заголовка после того, как он полностью зажат. Я должен это сделать сposition:"absolute"
и заставляя это представление следовать значению y. Проблема в том, что когда анимированный заголовок еще не полностью зажат, он кажется ЛАГГОВЫМ, а при прокрутке вверх он выглядит намного хуже. Вдобавок к этому индикатор прокрутки скрывается за положением:'абсолютный' вид панели фильтра... Я думаю, что решением было бы иметь это представление с относительной позицией, а затем изменить ее на абсолютную... но мне нужно знать, есть ли способ изменить стильposition:"relative"
к position:"absolute"
после того, как он будет зажат, чтобы он выглядел гладким, пока он не зажал, или, по крайней мере, способ сделать это, чтобы он не выглядел лагом, любая помощь очень приветствуется. здесь какой-то код (некоторые теги могут быть не закрыты, но суть вы понимаете):
constructor(props) {
super(props);
this.scrollY = new Reanimated.Value(0);
}
render() {
const translateY = multiply(min(this.scrollY, 0),-1);
const headerHeight = this.scrollY.interpolate({
inputRange: [0, HEADER_MAX_HEIGHT - HEADER_MIN_HEIGHT],
outputRange: [HEADER_MAX_HEIGHT, HEADER_MIN_HEIGHT],
extrapolate: Extrapolate.CLAMP
});
this.NewHeaderHeight= this.scrollY.interpolate({
inputRange: [0, HEADER_MIN_HEIGHT],
outputRange: [0, HEADER_MIN_HEIGHT + 1],
extrapolate: Extrapolate.CLAMP
});
const headerOpacity = this.scrollY.interpolate({
inputRange: [0, HEADER_SCROLL_DISTANCE / 3, HEADER_SCROLL_DISTANCE],
outputRange: [0, 0, 1],
extrapolate: Extrapolate.CLAMP
});
return(<View style={{flex:1}}>
{/* contenido */}
<Reanimated.ScrollView
style={[{flex:1}]}
bounces={false}
scrollEventThrottle={16}
onScroll={Reanimated.event([
{ nativeEvent: { contentOffset: { y: this.scrollY } } }
])}
>
{/* Start of animated HEADER */}
<View style={{height: HEADER_MAX_HEIGHT, width:'100%'}}>
{/* IMAGEN DEL HEADER Y ICONS*/}
<ImageBackground style={{flex:1, justifyContent:'center' }} source={{uri: 'https://images.unsplash.com/photo-etc}}>
//THERE WOULD BE SOME ICON AND OTHER CONTENT HERE DOESNT MATTER THOUGH
</ImageBackground>
</View>
*//there would be more children here doesnt matter either since filter toolbar is position:absolute for the moment*
</Reanimated.ScrollView>
{/*THIS IS FILTERBAR (here is where want to change the position style depending on scroll value)*/}
<Reanimated.View
style={[styles.categoryContainer, styles.shadow, { transform: [{translateY}],position: 'absolute', top: headerHeight, elevation:1, backgroundColor:'white'}]}
>
<FlatList
horizontal
data={infoDataFilter}
showsHorizontalScrollIndicator={false}
renderItem={({item}) => (
<TouchableOpacity
key={item.id}
style={[styles.categoryItem]}
activeOpacity={.7}
onPress={() => console.log(item.screen)}
>
<Text style={{paddingVertical: 5, fontSize:12, fontWeight:'bold', color: '#444444'}} >
{item.name.toUpperCase()}
</Text>
</TouchableOpacity>
)}
/>
</Reanimated.View>
что делает это:
https://www.youtube.com/watch?v=4GdnkUEdmko
Он отлично прокручивается, когда это представление имеет position:'relative', и я хотел бы, чтобы это было так, но изменилось на position:'absolute', когда анимированный заголовок был зажат.
РЕДАКТИРОВАТЬ: я использую собственную версию.61.5 reanimated ^1.7.0, обработчик жестов ^1.6.0, библиотеки реагирования навигации x4. это было протестировано на android samsung galaxy s6 devmode (то же самое на производстве)
1 ответ
Я не думаю менять position
опора - хорошая идея. Чтобы исправить "медленное" поведение, вы можете использоватьuseNativeDriver
на ваше Animated.event
и переместите анимацию на исходную сторону. Обычно он творит чудеса. Вот как это сделать:
Reanimated.event(
[{ nativeEvent: { contentOffset: { y: this.scrollY } } }],
{ useNativeDriver: true })
Хотя вы должны убедиться, что вы не управляете анимацией макета (шириной, высотой и т. Д.) С помощью scrollY
или вы получите сообщение об ошибке, так как они не поддерживаются.
РЕДАКТИРОВАТЬ
Я заметил, что вы ИСПОЛЬЗУЕТЕ scrollY для управления анимацией макета (headerHeight
). Чтобы сделать анимацию макета плавной, вы должны использоватьLayoutAnimation
. Это очень хорошая библиотека. Вот ссылка.