2017-01-27 1 views
1

Jedes Codebeispiel, wie man Animated.diffClamp implementiert?Wie man Animated.diffClamp in reaktivem nativem verwendet

Ich versuche eine Header-Scroll-Animation wie die in der Google Play App zu erstellen. Ich verstecke bereits die Kopfzeile, wenn Sie mit dem Scrollen beginnen, aber das Problem ist, dass ich die Kopfzeile wieder anzeigen möchte, sobald Sie mit dem Scrollen beginnen, es wird nur angezeigt, wenn Sie den oberen Rand der Ansicht erreichen.

class Services extends Component { 
    constructor(props){ 
    super(props); 
    this.state = { 
    scrollY : new Animated.Value(0), 
    } 
} 

renderScrollViewContent(){ 
    return (
    <View style={styles.scrollViewContent}> 
    </View> 
) 
} 

render() { 
    const headerHeight = this.state.scrollY.interpolate({ 
    inputRange: [0, 60], 
    outputRange: [0, -60], 
    extrapolate: 'clamp' 
    }); 

    return (
    <View style={styles.container}> 
     <ScrollView style={styles.container} 
     scrollEventThrottle={16} 
     onScroll={Animated.event(
      [{nativeEvent: {contentOffset: {y: this.state.scrollY}}}] 
     )} 
     > 
     {this.renderScrollViewContent()} 
     </ScrollView> 
     <Animated.View style={[styles.header, {top: headerHeight}]}> 
     <View style={styles.bar}> 
      <Text style={styles.title}>Title</Text> 
     </View> 
     </Animated.View> 
    </View> 
); 
} 
} 

Antwort

3

Wir haben dies genau für diesen Anwendungsfall hinzugefügt. Hier ist die Doc-Seite https://facebook.github.io/react-native/docs/animated.html#diffclamp

Ich empfehle auch, es mit einer Translate-Transformation zu verwenden (bessere perf und kann mit nativen Treiber verwendet werden). Hier ist Ihr Beispiel macht es mit:

const headerTranslate = Animated.diffClamp(this.state.scrollY, 0, 60) 
    .interpolate({ 
    inputRange: [0, 1], 
    outputRange: [0, -1], 
    }); 

return (
<View style={styles.container}> 
    <ScrollView style={styles.container} 
    scrollEventThrottle={16} 
    onScroll={Animated.event(
     [{nativeEvent: {contentOffset: {y: this.state.scrollY}}}] 
    )} 
    > 
    {this.renderScrollViewContent()} 
    </ScrollView> 
    <Animated.View style={[styles.header, {transform: [{translateY: headerTranslate}]}]}> 
    <View style={styles.bar}> 
     <Text style={styles.title}>Title</Text> 
    </View> 
    </Animated.View> 
</View> 
); 

Wie es funktioniert ist, dass wir die Bildlaufposition zu diffClamp passieren, so dass es zwischen 0 und 60 eingespannt ist, nachdem wir Interpolation verwenden, um den Wert negativ zu machen (wir wollen, dass es übersetzen up).

+1

Ich versuche diffClamp mit Animated.event mit nativen Treiber zu implementieren. Aber ich habe anscheinend sehr wenig Kontrolle über das Ergebnis des animierten Wertes. Ich möchte die gleiche Kopfzeile wie die iOS Facebook App, aber ich laufe in mehrere Probleme. Ich kann nicht verhindern, dass sich der Header am oberen Rand der Ansicht versteckt oder die Ansicht überdreht. Auch wenn der Benutzer den Bildlauf stoppt, während sich die Navigationsleiste in der Mitte der Folienanimation befindet, sollte sie zu vollständig ausgeblendet/sichtbar animiert werden. Ich sehe nicht, wie ich irgendwelche von diesen implementieren kann, wenn ich den gegenwärtigen Scroll-Wert von dem Ereignis nicht lesen kann. – David

+0

Die Implementierung ist komplizierter, aber es ist möglich, einen animierten Wert-Listener zu verwenden. Sie können Ihren Scroll Animated.Value verwenden und ihm einen Listener hinzufügen und dieselbe Logik implementieren wie diffClamp, um den aktuellen Wert zu erhalten und entsprechend zu animieren, wenn das Scrollen stoppt. Ich habe es implementiert, aber leider kann ich das Repo nicht mehr finden. –

+0

Vielen Dank für den Hinweis. Ich dachte nicht, dass der Wert des Zuhörers so leistungsfähig wäre, dass er als Wert für die Animation verwendet werden könnte, aber es scheint, dass er genauso ausgeführt wird wie der animierte Wert des Ereignisses. Momentan übergebe ich den Wert vom Listener an eine Funktion, die die benötigten Berechnungen inkl. die Klemmung und dann setValue auf einen neuen animierten Wert, der für die Animation verwendet wird. Ist das mehr oder weniger so, wie Sie es implementiert haben, oder sollte ich es anders machen? – David

Verwandte Themen