如何在键盘弹出时自动向上滚动软键盘上方的聊天消息(使用recyclerview而不是listview)?

时间:2015-09-21 06:14:49

标签: android android-fragments android-recyclerview android-design-library android-developer-api

就像聊天应用程序一样,每当我们想要发送消息时,软键盘弹出窗口也会自动将最后看到的消息滚动到软键盘的顶部,前提是软键盘后面没有任何东西。但在我的情况下,键盘会隐藏对话。如何解决这个问题,我已经习惯了回收站视图来显示消息。我使用了android.support.v7.widget.RecyclerView

3 个答案:

答案 0 :(得分: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);

答案 1 :(得分:2)

我如何处理这个非常简单,实现一个好的行为,类似于Whatsapp或其他流行的聊天。

首先,像这样设置LinearLayoutManager

 new LinearLayoutManager(this.getContext(), LinearLayoutManager.VERTICAL, true);
 chatLayoutManager.setStackFromEnd(true);

当消息开始溢出底部的RecyclerView时,需要将当前位置设置为0,为实现此目的,一个简单的界面就像魅力一样,在RecyclerView.Adapter呈现时发出警告最后一条消息。

public interface OnLastItemRendered{

    void lastItemRendered();

}

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

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();
}

并且,对于在开头加载的X消息,在onBindViewHolder

@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();
}

完成工作。

答案 2 :(得分: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()。