2017-04-30 11 views
8

私はFlatListを使用していますが、各行の高さは異なる場合があります(テキストと0以上のイメージが混在している可能性があります)。行が可変である場合のFlatListのスクロールの問題

計算できるように各行(以前のもの)の高さがわからないため、getItemLayoutを使用することはできません。

私が直面している問題は、リストの末尾までスクロールできないことです(試してみるとわずかな行にジャンプします)。scrollToIndexを使用しようとすると問題が発生しています(私は事実私は逃しているgetItemLayout)。

私は、問題を示すために、サンプルプロジェクトを書いた:

import React, { Component } from 'react'; 
import { AppRegistry, StyleSheet, Text, View, Image, FlatList } from 'react-native'; 
import autobind from 'autobind-decorator'; 

const items = count => [...Array(count)].map((v, i) => ({ 
    key: i, 
    index: i, 
    image: 'https://dummyimage.com/600x' + (((i % 4) + 1) * 50) + '/000/fff', 
})); 

class RemoteImage extends Component { 
    constructor(props) { 
     super(props); 
     this.state = { 
      style: { flex: 1, height: 0 }, 
     }; 
    } 

    componentDidMount() { 
     Image.getSize(this.props.src, (width, height) => { 
      this.image = { width, height }; 
      this.onLayout(); 
     }); 
    } 

    @autobind 
    onLayout(event) { 
     if (event) { 
      this.layout = { 
       width: event.nativeEvent.layout.width, 
       height: event.nativeEvent.layout.height, 
      }; 
     } 
     if (!this.layout || !this.image || !this.image.width) 
      return; 
     this.setState({ 
      style: { 
       flex: 1, 
       height: Math.min(this.image.height, 
        Math.floor(this.layout.width * this.image.height/this.image.width)), 
      }, 
     }); 
    } 
    render() { 
     return (
      <Image 
       onLayout={this.onLayout} 
       source={{ uri: this.props.src }} 
       style={this.state.style} 
       resizeMode='contain' 
      /> 
     ); 
    } 
} 

class Row extends Component { 
    @autobind 
    onLayout({ nativeEvent }) { 
     let { index, item, onItemLayout } = this.props; 
     let height = Math.max(nativeEvent.layout.height, item.height || 0); 
     if (height != item.height) 
      onItemLayout(index, { height }); 
    } 

    render() { 
     let { index, image } = this.props.item; 
     return (
      <View style={[styles.row, this.props.style]}> 
       <Text>Header {index}</Text> 
       <RemoteImage src = { image } /> 
       <Text>Footer {index}</Text> 
      </View> 
     ); 
    } 
} 

export default class FlatListTest extends Component { 
    constructor(props) { 
     super(props); 
     this.state = { items: items(50) }; 
    } 

    @autobind 
    renderItem({ item, index }) { 
     return <Row 
     item={item} 
     style={index&1 && styles.row_alternate || null} 
     onItemLayout={this.onItemLayout} 
     />; 
    } 

    @autobind 
    onItemLayout(index, props) { 
     let items = [...this.state.items]; 
     let item = { ...items[index], ...props }; 
     items[index] = { ...item, key: [item.height, item.index].join('_') }; 
     this.setState({ items }); 
    } 

    render() { 
     return (
      <FlatList 
        ref={ref => this.list = ref} 
        data={this.state.items} 
        renderItem={this.renderItem} 
       /> 
     ); 
    } 
} 

const styles = StyleSheet.create({ 
    row: { 
     padding: 5, 
    }, 
    row_alternate: { 
     backgroundColor: '#bbbbbb', 
    }, 
}); 

AppRegistry.registerComponent('FlatListTest',() => FlatListTest); 
+0

** Gilad Novik **、この問題を解決していますか?私は同じ問題を抱えています。 – Kholiavko

+1

@Kholiavko悲しいことに、解決策がまだ見つかりませんでした。最新のRNリリースにはまだこの問題があります:( –

答えて

1

だから私は、あなたが行うことができると思う何をして格納することであるため、あなたはすでに店舗を持っているもの行のインデックスによるコレクションonLayoutreturned by getItemLayout{length: number, offset: number, index: number}の属性を格納することをお勧めします。

getItemLayoutを実装すると、passes an indexは、保存したレイアウトを返すことができます。これにより、scrollToIndexの問題が解決されるはずです。これをテストしていないが、これは正しいアプローチのようだ。

関連する問題