web-dev-qa-db-ja.com

Reactネイティブ:アイテムセパレータを使用した水平方向のFlatListでの正しいスクロール

リアクトネイティブ: v0.52.0

プラットフォーム:iOS

私のFlatListコード:

<FlatList
  horizontal
  pagingEnabled={true}
  showsHorizontalScrollIndicator={false}

  legacyImplementation={false}

  data={this.props.photos}
  renderItem={item => this.renderPhoto(item)}
  keyExtractor={photo => photo.id}

  ItemSeparatorComponent={this.itemSeparatorComponent}
/>

アイテムセパレータコード:

itemSeparatorComponent = () => {
    return <View style = {
        {
            height: '100%',
            width: 5,
            backgroundColor: 'red',
        }
    }
    />
}

そして最後にFlatList項目コンポーネント:

renderPhoto = ({ item, index }) => {
    return (
        <View style = {{ width: SCREEN_WIDTH, height: 'auto' }}>
          <FastImage 
            style = { styles.photo }
            resizeMode = { FastImage.resizeMode.contain }
            source = {{ uri: item.source.uri }}
          /> 
        </View>
    )
}

しかし、スクロールするとき、FlatListはセパレーターへのオフセットを作成しますが、アイテムの左端へのオフセットは作成しません。

enter image description here

そして、新しい要素ごとに、FlatListは前のすべてのセパレーターの幅をオフセットに追加します。

enter image description here

FlatListコンポーネントに、水平スクロールでセパレーターコンポーネントの幅を考慮させ、適切なオフセットを設定する方法

4
Yury

私は同じユースケースを持っていました。解決策を探している人のために、ここにあります。

ステップ1)ItemSeparatorComponent propを使用しないでください。代わりに、renderItemコンポーネントでインラインにレンダリングします。

ステップ2)(キーポイント)。 widthheightプロパティでstyleFlatListを指定します。あなたの場合、widthSCREEN_WIDTH + 5である必要があります。

次に、ページ付けが有効になっている場合、Flatlistは自動的に画面全体(写真+セパレータ)を移動します。これで、コードは次のようになります。

<FlatList
  horizontal
  pagingEnabled={true}
  showsHorizontalScrollIndicator={false}
  legacyImplementation={false}
  data={this.props.photos}
  renderItem={item => this.renderPhoto(item)}
  keyExtractor={photo => photo.id}
  style={{width: SCREEN_WIDTH + 5, height:'100%'}}
/>

写真コードをレンダリングする:-

renderPhoto = ({ item, index }) => {
return (
    <View style = {{ width: SCREEN_WIDTH + 5, height: 'auto', 
      flexDirection:'row'}}>
      <FastImage 
        style = { styles.photo }
        resizeMode = { FastImage.resizeMode.contain }
        source = {{ uri: item.source.uri }}
      /> 
      {this. itemSeparatorComponent()}
    </View>
)}

アイテムセパレータコード:

itemSeparatorComponent = () => {
return <View style = {
    {
        height: '100%',
        width: 5,
        backgroundColor: 'red',
    }
}
/>
}

それでも理解できない場合は、次のコンポーネントを見てください。
https://github.com/zachgibson/react-native-parallax-swiper

実装に入ると、この人がAnimated.ScrollViewに幅と高さを提供していることがわかります。
https://github.com/zachgibson/react-native-parallax-swiper/blob/master/src/ParallaxSwiper.js
行番号:93-97

3
Yash Gadle

renderPhoto関数で返す最上位のビューの幅はSCREEN_WIDTHですが、ItemSeparatorComponent各アイテムの間にレンダリングされる は、スタイルの定義に従って5の幅を占めています。その結果、スクロールする追加の項目ごとに、その初期オフセットは左側に5ピクセル多くなります。

これを修正するには、ItemSeparatorComponentを完全に削除するか(pagingEnabledを既にtrueに設定しているため)、renderPhotoに返されるトップレベルビューの幅をSCREEN_WIDTH - 2.5に設定します。これにより、1つの写真の右端にアイテムセパレータの半分が表示され、次の写真の左端に残りの半分が表示されます。

実際には、もう1つの可能な解決策は、アイテムセパレーターを削除し、renderPhotoViewの幅をSCREEN_WIDTH + 5に設定して、これらの追加のプロパティをスタイルに含めることです:{paddingRight: 5, borderRightWidth: 5, borderRightColor: 'red'}。この方法では、pagingEnabledプロパティのため、左と右にスクロールするまで赤いセパレーターは表示されません。

1
Pat Needham