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