react-native FlatList 滚动到底部的聊天应用程序

Posted

技术标签:

【中文标题】react-native FlatList 滚动到底部的聊天应用程序【英文标题】:react-native FlatList scroll to bottom for chat app 【发布时间】: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 开箱即用的。 这是我包装平面列表的内容组件的问题。通过用视图替换它来修复它。非常感谢您宝贵的时间和帮助。 【参考方案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>
    );
  

【讨论】:

以上是关于react-native FlatList 滚动到底部的聊天应用程序的主要内容,如果未能解决你的问题,请参考以下文章

react-native FlatList 滚动到底部的聊天应用程序

在 Android 的 FlatList (React Native) 中隐藏滚动条

突出显示 React-Native FlatList 中的选定项目

React Native - FlatList - 内部状态

FlatList vs map react-native

React Native FlatList 没有滚动到结束