【问题标题】:react-native FlatList scroll to bottom for chat appreact-native FlatList 滚动到底部的聊天应用程序
【发布时间】:2020-07-19 16:10:29
【问题描述】:

我制作了一个聊天应用程序,并使用平面列表来呈现消息。但是问题是每次加载页面时都尝试滚动到屏幕末尾,但它失败了。我试过倒置的道具,但什么也没发生,只有列表倒置了。

甚至使用 ref 让它自动滚动到底部,但什么也没发生。

<FlatList
  ref="flatList"
  onContentSizeChange={() =>
    this.refs.flatList.scrollToEnd()}
  contentContainerStyle={{
    marginBottom:
      verticalScale(200)
  }}
  style={styles.list}
  data={this.state.messages}
/>

如何让它在渲染时滚动到屏幕底部或滚动到消息的最后一个索引?

(更新)

这是我使用的属于 native-base 的 &lt;Content/&gt; 组件的问题。在删除并用&lt;View/&gt; 替换它后,它工作得非常好。 此外,对于基于聊天的应用,Flatlist 中的 inverted 属性是正确实现的方法。

我在下面的答案中添加了我设法滚动的方式。如果您只是希望您的应用显示列表中的最后一项并停留在那里,您可以使用inverted

【问题讨论】:

  • 你使用的是哪个版本的 react-native?我在一个新的、空的 RN 0.62 项目中尝试了以下两个示例:gist.github.com/mlisik/27165a6cf538d5ce3591d1da16afdbf5 它们都按预期工作(这表明您的代码也应该如此)。旁注:我不认为您真的想在每次收到新消息时都滚动到底部。只有当用户已经向下滚动时才会发生这种情况(否则他们可能无法阅读过去的消息) - 这种情况实际上是通过inverted FlatList 开箱即用的。
  • 这是我包装平面列表的内容组件的问题。通过用视图替换它来修复它。非常感谢您宝贵的时间和帮助。

标签: react-native react-native-flatlist


【解决方案1】:

你应该像这样使用 ref:

    export default class MyAwesomeComponent extends React.Component {
      FlatListRef = null; // add a member to hold the flatlist ref
    
      render() {
        return (
          <FlatList
            ref={ref => (this.FlatListRef = ref)} // assign the flatlist's ref to your component's FlatListRef...
            onContentSizeChange={() => this.FlatListRef.scrollToEnd()} // scroll it
            contentContainerStyle={{marginBottom: verticalScale(200)}}
            style={styles.list}
            data={this.state.messages}
          />
        );
      }
    }

【讨论】:

    【解决方案2】:

    prueba esto

    return (
          <View style={{flex: 1}}>
            <KeyboardAvoidingView
              behavior="padding"
              style={styles.keyboard}
              keyboardVerticalOffset={height - 1000}>
              <FlatList
                ref={ref => (this.FlatListRef = ref)}
                onContentSizeChange={() => this.FlatListRef.scrollToEnd()} // scroll it
                // contentContainerStyle={{marginBottom: verticalScale(200)}}
                // keyboardShouldPersistTaps='always'
                style={styles.list}
                extraData={this.state}
                data={this.state.messages}
                keyExtractor={item => {
                  return item.id;
                }}
                renderItem={e => this._renderItem(e)}
              />
              <View style={styles.input}>
                <TextInput
                  // style={{flex: 1}}
                  value={msg}
                  placeholderTextColor="#000"
                  onChangeText={msg => this.setState({msg: msg})}
                  blurOnSubmit={false}
                  onSubmitEditing={() => this.send()}
                  placeholder="Escribe el mensaje"
                  returnKeyType="send"
                />
              </View>
            </KeyboardAvoidingView>
          </View>
        );
    

    【讨论】:

      【解决方案3】:

      您可以使用 Javascript 方法反向显示您的消息从头开始

      messages.reverse()
      

      【讨论】:

      • 实际上我需要的不是反转消息。我需要将列表滚动到最后一个项目或消息;就像在普通的聊天应用中一样。
      • 你的意思是你想让最新消息显示在底部?
      • 是的..列表应该呈现所有消息然后用户视图应该是最后一条消息或滚动到最后一条消息
      • message.reverse() 对我有用。它呈现所有消息,最新消息将显示在屏幕底部
      • 现在消息呈现没有任何问题。最新消息显示在底部,但是 - 我需要滚动到列表底部。
      【解决方案4】:
      scrollToListPosition = (index) => {
        const itemOffset = this.getItemOffset(index)
        this.flatListRef.scrollToOffset({ animated: false, offset: itemOffset })
      }
      
      getItemOffset = (index) => {
        let heightsum = 0
        for (i = 0; i < index; i++) {
          heightsum = heightsum + this.itemHeight[i]
        }
        return heightsum
      }
      
      
      render(){
        return (
          <FlatList
            ref={(ref) => { this.flatListRef = ref; }}
            data={postList}
            keyExtractor={(item, index) => item._id}
            horizontal={false}
            extraData={this.state}
            keyboardShouldPersistTaps='always'
            refreshing={this.props.isRefreshing}
            onRefresh={this.handleRefresh}
            onEndReached={this.handleLoadMore}
            getItemLayout={(data, index) => (
              { length: this.getLength(index), offset: this.getLength(index) * index, index }
            )}
            renderItem={({ item, index }) => {
              return (
                <View onLayout={(event) => {
                  var { height } = event.nativeEvent.layout;
                  this.itemHeight[index] = height
                }}
                >
                  <ListCommon
                    key={index}
                    item={item}
                    index={index}
                    parentFlatList={this}
                    data={item}
                    instance={this.props.commanAction}
                    tag={this.state.tag}
                    changeRoute={this.props.changeRoute}
                  />
                </View>
              );
            }}
          />
        )
      }
      
      getLength = (index) => {
        if (this.itemHeight[index] === undefined) {
          return 0;
        }
        return this.itemHeight[index]
      }
      

      【讨论】:

      • getLength() 有什么作用?? @Rajan
      【解决方案5】:

      我是这样解决的:

      export default class Test extends Component {
        constructor(props) {
          super(props);
        }
        componentDidMount() {
          setTimeout(() => {
            this.FlatListRef.scrollToEnd();
          }, 1500);
        }
        render() {
          return (
            <View style={{ flex: 1 }}>
              <FlatList
                data={[1, 2, 3, 4, 5, 6, 7, 8]}
                ref={(ref) => (this.FlatListRef = ref)}
                renderItem={({ item }) => {
                  return (
                    <View
                      style={{
                        height: 140,
                        width: 400,
                        backgroundColor: "yellow",
                        alignItems: "center",
                        justifyContent: "center",
                      }}
                    >
                      <Text>{item}</Text>
                    </View>
                  );
                }}
              />
            </View>
          );
        }
      

      }

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-24
        • 2020-11-17
        • 2018-10-30
        • 1970-01-01
        • 2018-09-20
        • 1970-01-01
        相关资源
        最近更新 更多