Есть ли способ изменить положение стилей: «по отношению» к положению: «абсолютное» в зависимости от значения прокрутки Y в Animated.ScrollView React-Native - PullRequest
1 голос
/ 07 марта 2020

У меня есть анимированный заголовок, который становится меньше и увеличивается непрозрачность, когда прокручивается представление прокрутки вниз. Под этим есть полоса фильтра, которой нужно придерживаться чуть ниже анимированного заголовка после того, как он полностью зажат. Я получил это, чтобы сделать это с position:"absolute" и заставить это представление следовать за значением y. Проблема в том, что кажется LAGGY , когда анимированный заголовок еще не полностью зажат, а при прокрутке он выглядит намного хуже. Вдобавок к этому индикатор прокрутки скрывается за позицией: «абсолютный» вид панели фильтра ... Я думаю, что решением было бы иметь это представление с относительным положением, а затем изменить его на абсолютное ... но мне нужно знать, есть ли способ изменить стиль 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

Он прекрасно прокручивается, когда у этого представления есть позиция: «относительная», и я хотел бы, чтобы это было так, но я изменяю на позицию: «абсолютная», когда анимированный заголовок зажат ..

РЕДАКТИРОВАТЬ: я использую реагировать родная версия .61.5 реанимирована ^ 1.7.0, обработчик жестов ^ 1.6.0, реагирует навигация x4 библиотеки. это было протестировано на android Samsung Galaxy S6 Devmode (то же самое на производстве)

1 Ответ

0 голосов
/ 07 марта 2020

Я не думаю, что замена position хорошая идея. Чтобы исправить «запаздывающее» поведение, вы можете использовать useNativeDriver на вашем Animated.event и переместить анимацию на исходную сторону. Это обычно делает чудеса. Вот как вы это делаете:

Reanimated.event( [{ nativeEvent: { contentOffset: { y: this.scrollY } } }], { useNativeDriver: true })

Хотя вы должны быть уверены, что не запускаете анимацию макета (ширину, высоту и т. Д. c) с помощью scrollY или вы получите сообщение об ошибке, поскольку они не поддерживаются.

EDIT

Я заметил, что вы используете scrollY для управления анимацией макета (headerHeight). Чтобы сделать анимацию макета гладкой, вы должны использовать LayoutAnimation. Это очень хорошая библиотека. Вот ссылка .

...