2017-05-03 7 views
1

私のプロジェクトでは、あなたが名刺の箱を閲覧しているかのようにアイテムを表示するScrollViewを実装しようとしています。私は現在の実装をAlbert Brand's article on Animated ScrollViewsに基づいています(他の多くのアプローチを試した後)。アニメーションの余白を滑らかにする方法ScrollViewの上のトランジション?

しかし、今は全体が非常にやわらかくなります。誰も現在の実装をスムーズにする方法を私にアドバイスできますか?別の方法として、どのようにこの動作を取得するヒントを誰も持っていますか?すべてのソリューションはiOSとAndroidの両方で動作するはずです。

このgifは、ジッタの問題を含む現在の実装を示しています。また、私が後だ何の行動の鮮明な画像が得られます: screencapture of the ScrollView in iOS simulator

これは私の現在の実装である:

import React from 'react' 
import { 
    Animated, 
    Dimensions, 
    ScrollView, 
    StyleSheet, 
    Text, 
    View, 
    StatusBar, 
} from 'react-native' 

const SCREEN_HEIGHT = Dimensions.get('window').height 

const yOffset = new Animated.Value(0) 

const onScroll = Animated.event(
    [{ nativeEvent: { contentOffset: { y: yOffset } } }], 
) 

function CardView(props: { children?: ReactElement<*> }) { 
    return (
    <Animated.ScrollView 
     scrollEventThrottle={16} 
     onScroll={onScroll} 
     pagingEnabled 
    > 
     {props.children} 
    </Animated.ScrollView> 
) 
} 

function Page(props: { children?: ReactElement<*>, index: 1 }) { 
    return (
    <Animated.View style={[style.scrollPage]}> 
     {props.children} 
    </Animated.View> 
) 
} 

function Card(props: { text: string, index: number }) { 
    return (
    <Animated.View style={[style.card, marginTransform(props.index)]}> 
     <Text> 
     {props.text} 
     </Text> 
    </Animated.View> 
) 
} 

function marginTransform(index: number) { 
    return { 
    marginTop: yOffset.interpolate({ 
     inputRange: [ 
     (index - 1) * SCREEN_HEIGHT, 
     index * SCREEN_HEIGHT, 
     (index + 1) * SCREEN_HEIGHT, 
     (index + 2) * SCREEN_HEIGHT, 
     (index + 3) * SCREEN_HEIGHT, 
     ], 
     outputRange: [ 
     -40, 
     80, 
     SCREEN_HEIGHT + 40, 
     2 * SCREEN_HEIGHT + 20, 
     3 * SCREEN_HEIGHT, 
     ], 
     extrapolate: 'clamp', 
    }), 
    } 
} 

export default function App() { 
    return (
    <CardView> 
     {[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((i) => { 
     return(
      <Page key={i}> 
      <Card text={`Card ${i}`} index={i}> 
      </Card> 
      </Page> 
     ) 
     })} 
    </CardView> 
) 
} 

const style = StyleSheet.create({ 
    scrollPage: { 
    height: SCREEN_HEIGHT, 
    backgroundColor: 'transparent', 
    }, 
    card: { 
    height: SCREEN_HEIGHT, 
    alignItems: 'center', 
    borderRadius: 4, 
    borderWidth: 1, 
    backgroundColor: '#F5FCFF', 
    } 
}) 

答えて

0

私が見つけた短い答え:ScrollViewsは、スクロールしながら高さを混乱させると滑らかにアニメートされません。私が設定したときにパフォーマンスが大幅に改善されたことがわかりましたscrollEventThrottle={1}

私が実装したソリューションは、自分のコンポーネントを作成していました。 ScrollViewを要素のリストの上にレンダリングします。私はこれらの要素のAnimated height値をScrollViewのスクロールyオフセットに接続しました。誰もがこれまでと同じユースケース実装の問題に遭遇した場合、私の作品を使用して自由に感じる

https://github.com/isilher/react-native-card-scroll

0

は、デバッグJS Remoteが無効になっていることを確認してください。また、クラス内のconsole.log()をすべて削除する必要があります(デバッグのためにyOffsetをログに記録する場合など)。これは事をスピードアップするはずです。

+0

はあなたにルカありがとうラグの乗り心地を取得するのに役立ちますしてみてください、私はこれを試しましたが、ここでは最適化は問題ではありません。ジッタの原因は、スクロール中のmarginTopを更新すると、ScrollView全体のレンダリングも混乱することです。私はそれをどのように解決するか考えていない。 – Isilher

+0

(marginTopではなく)topを更新し、位置を 'absolute'に設定してください。 –

+0

これは同じ結果をもたらすようです。もう1つの欠点は、marginTopとtop offsetの両方がカードをコンテナの外にレンダリングすることです.Androidはそれらを切り捨てます。私はまったく異なる実装を探す必要があります。ご協力いただきありがとうございます! 「scrollEventThrottle = {1}」を16の代わりに設定すると、奇妙な振る舞いがよりスムーズになりました。しかし実際にはあまりにも不安定です。 – Isilher

-1

ちょっとこのuseNativeDriver: true

onScroll={Animated.event(
    [{ nativeEvent: { contentOffset: { x: xOffset } } }], 
    { useNativeDriver: true } 
)} 
関連する問題