Android 具有多重布局的RecyclerView是';t正确更新或在新数据上崩溃
所以我用firebase创建聊天应用程序,并使用实时数据库存储聊天室和聊天室。我创建了一个recyclerview,用从firebase获取的列表更新聊天ui。数据提取工作正常,但使用新数据更新ui会使应用程序崩溃- 这是我的适配器-Android 具有多重布局的RecyclerView是';t正确更新或在新数据上崩溃,android,firebase,android-recyclerview,Android,Firebase,Android Recyclerview,所以我用firebase创建聊天应用程序,并使用实时数据库存储聊天室和聊天室。我创建了一个recyclerview,用从firebase获取的列表更新聊天ui。数据提取工作正常,但使用新数据更新ui会使应用程序崩溃- 这是我的适配器- public class ChatAdapter extends RecyclerView.Adapter{ private List<Chat> msgList; private String user; public C
public class ChatAdapter extends RecyclerView.Adapter{
private List<Chat> msgList;
private String user;
public ChatAdapter(String user,List<Chat> msgList) {
this.msgList = msgList;
this.user = user;
}
@Override
public int getItemViewType(int position) {
if(!msgList.get(position).getUser().equals(user)){
return 1;
}
return 0;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view;
if(viewType==1){
view = layoutInflater.inflate(R.layout.chat_right,parent,false);
return new RightChat(view);
}else{
view = layoutInflater.inflate(R.layout.chat_left,parent,false);
return new LeftChat(view);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int i) {
if(msgList.get(i).getUser().equals(user)) {
LeftChat viewLeft = (LeftChat) holder;
viewLeft.msgView.setText(msgList.get(getItemCount() - i - 1).getMsg());
viewLeft.timeView.setText(msgList.get(getItemCount() - i - 1).getTime());
}else{
RightChat viewRight = (RightChat) holder;
viewRight.msgView.setText(msgList.get(getItemCount()-i-1).getMsg());
viewRight.timeView.setText(msgList.get(getItemCount()-i-1).getTime());
}
}
@Override
public int getItemCount() {
return msgList.size();
}
class LeftChat extends RecyclerView.ViewHolder{
TextView msgView,timeView;
public LeftChat(@NonNull View itemView) {
super(itemView);
msgView = itemView.findViewById(R.id.tv_1);
timeView = itemView.findViewById(R.id.tm_1);
}
}
class RightChat extends RecyclerView.ViewHolder{
TextView msgView,timeView;
public RightChat(@NonNull View itemView) {
super(itemView);
msgView = itemView.findViewById(R.id.tv_2);
timeView = itemView.findViewById(R.id.tm_2);
}
}
}
错误-Reyclerview无法将leftview转换为rightview,反之亦然
到目前为止,我所尝试的是在适配器中更改了视图,它对firebase中已经存在的消息起作用,但一旦我创建了新消息,它就会再次崩溃。所以我不知道逻辑在哪里失效。此外,我还尝试在没有应用程序的情况下手动在firebase中添加新数据,但它也会使firebase崩溃。我在您的代码中看到一些错误,在这里
if(msgList.get(i).getUser().equals(user)) {
LeftChat viewLeft = (LeftChat) holder;
viewLeft.msgView.setText(msgList.get(getItemCount() - i - 1).getMsg());
viewLeft.timeView.setText(msgList.get(getItemCount() - i - 1).getTime());
}else{
RightChat viewRight = (RightChat) holder;
viewRight.msgView.setText(msgList.get(getItemCount()-i-1).getMsg());
viewRight.timeView.setText(msgList.get(getItemCount()-i-1).getTime());
}
您正在按位置i
检查viewType
(msgList.get(i)
inif
),但试图在数组中的getItemCount()-i-1
位置上绘制项,因此不同的项,因此viewType
可能不匹配
重写getItem(int position)
方法,在其中返回msgList.get(position)
,当需要msg
时,始终使用getItem
,例如在onBindViewHolder
和getItemViewType
中,这是获取模型的统一方法。不要混淆位置,如果你被称为onBindViewHolder
和positioni
,那么使用项目表单positioni
如果您需要恢复订单,只需在构造函数中恢复订单即可谢谢您的回复。我之所以使用getcount()-I-1,是因为我希望以与底部最新列表相反的顺序显示列表,如whatsapp。我曾经按照你建议的方式加载列表,但它会从上到下加载我的数据。你检查不同的条件,然后使用不同的东西,这不是逻辑。您正在检查位置
i
的viewType
,并使用mesage from positiongetItemCount()-i-1
-这些项目不同,舒尔可能需要不同的布局。我还写过,若你们需要颠倒顺序,只需改变构造函数中的顺序。你试过我的建议吗?嘿,对不起,我想我可以用Collection.reverse()来做。我不需要从底部拿东西。非常感谢您首先制作舒尔,如果条件与您想要绘制的相同项目/消息有关,请。很高兴听到你的代码现在起作用了,考虑一下,如果有帮助的话,请接受我的回答:祝你好运!
if(msgList.get(i).getUser().equals(user)) {
LeftChat viewLeft = (LeftChat) holder;
viewLeft.msgView.setText(msgList.get(getItemCount() - i - 1).getMsg());
viewLeft.timeView.setText(msgList.get(getItemCount() - i - 1).getTime());
}else{
RightChat viewRight = (RightChat) holder;
viewRight.msgView.setText(msgList.get(getItemCount()-i-1).getMsg());
viewRight.timeView.setText(msgList.get(getItemCount()-i-1).getTime());
}