如何在软键盘弹出时,使用RecyclerView而不是ListView自动滚动聊天消息到软键盘上方?

3

在聊天应用程序中,当我们想要发送消息时,软键盘会弹出,并自动滚动到软键盘顶部的最后一条已读消息,前提是没有任何内容被隐藏在软键盘后面。但在我的情况下,键盘会隐藏对话。如何解决这个问题?我使用了android.support.v7.widget.RecyclerView来显示消息。


请查看以下内容:https://dev59.com/PGEi5IYBdhLWcg3whckh - Evgeny Maltsev
我尝试了那个链接里的解决方案,但对我没有起作用!!! 不管怎样还是谢谢... - Kalaiselvan
3个回答

4
使用RecyclerView,您可以按照以下方式实现此目标:
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setReverseLayout(true);
recyclerView.setLayoutManager(linearLayoutManager);

以下代码块将告诉RecyclerView相对于列表底部滚动,但它还以相反的顺序显示消息,因此在您的代码中,如果您从数据库中获取消息,请像这样从最后一条消息中读取它们:

Cursor c = ...;
c.moveToLast();
do{
//your code which gets messages from cursor...
}while(c.moveToPrevoius());

当你想要向列表中添加新消息时,只需像这样添加它们:

//ArrayList messages
messages.add(0, message);

谢谢... 代码的第一部分部分地达到了我的期望,即当我开始输入最后查看的消息时,它会出现在键盘上方,到目前为止还不错。但是我还需要发送消息时它也应该出现在最后查看的消息中,以便它像 WhatsApp 或其他社交消息应用程序中发送的聊天应用程序一样。 - Kalaiselvan
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Saeed Entezari

2
我会很简单地处理这个问题,实现一种类似于WhatsApp或其他流行聊天应用的良好行为。
首先,设置LinearLayoutManager如下所示。
 new LinearLayoutManager(this.getContext(), LinearLayoutManager.VERTICAL, true);
 chatLayoutManager.setStackFromEnd(true);

当消息开始在底部溢出RecyclerView时,需要将当前位置设置为0,为实现此目的,一个简单的接口可以起到很好的作用,它会在RecyclerView.Adapter渲染最后一条消息时发出警告。

public interface OnLastItemRendered{

    void lastItemRendered();

}

将接口实现从activity/fragment传递到RecyclerView.Adapter,以调用RecyclerView中的scrollToPosition

new ChatMessageListAdapter(
    context, user, lastOldMessages,
    new OnLastItemRendered() {

        @Override
        public void lastItemRendered() {

            ContainerFragment.this.myRecyclerViewToChat.scrollToPosition(0);
    }
});

最后,如果想在 RecyclerView 中执行动画,需要实现一个方法将消息添加到 RecyclerView.Adapter,并在最后调用 notifyItemInserted 方法。

public void add(ChatMessage chatMessage) {

    if (this.chatMessages == null) {

        this.chatMessages = new ArrayList<ChatMessage>();
    }

    this.chatMessages.add(chatMessage);

    Collections.sort(this.chatMessages, this.orderChatMessagesComparator);

    this.notifyItemInserted(0);

    this.onLastItemRendered.lastItemRendered();
}

onBindViewHolder中,对于一开始加载的X条消息。

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

    final ChatMessage currentMessage = this.chatMessages.get(position);

    ... //Do your stuff.

    if (position == 0) this.onLastItemRendered.lastItemRendered();
}

工作完成。


0
你可以检测编辑文本的焦点,如果你的editText有焦点,就将你的recyclerView列表滚动到最后一个元素。
private OnFocuseChangeListener focuseListener = new OnFocuseChangeListener(){
  public void onFocusChange(View v, boolean hasFocus){
            if(hasFocus){

            // Scroll down to the last element of the list
            recyclerView.scrollToPosition(sizeOfYourList);

          } else {
              focusedView  = null;
        }
    }
}

同样地,当您点击发送按钮或想要显示列表的最后一个元素时,请使用 scrollToPosition()。


你能详细解释一下吗?我是一个Android开发的初学者。实际上,我正在使用Recycler View,其中包含聊天列表和一个带有发送按钮的编辑文本。当我输入消息时,键盘会隐藏聊天记录,因此这些聊天记录应该在键盘上方自动滚动... - Kalaiselvan
只需在输入文本消息的editText上设置setOnfocusChangeListener。像这样:editText.setOnFoucsChangeListener(focuseListener);然后使用上面的代码来检测editText的焦点。每次触摸editText时,它都会获得焦点,并且每次调用上面代码中的focusListener。因此,调用recyclerView.ScrollToPosition(sizeOfYourList)方法。它会将您带到列表的最后一行。类似地,在单击发送按钮时调用此方法。 - Er.Rohit Sharma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接