【问题标题】:Populate one custom adapter with two array list in recyclerview在 recyclerview 中用两个数组列表填充一个自定义适配器
【发布时间】:2017-01-10 03:02:07
【问题描述】:

我有两个 arraylist,我想在同一个 recyclerview 中显示两个列表中的数据。我的代码如下所示。

我的适配器

class NotificationAdapter extends     RecyclerView.Adapter<NotificationViewHolder> {
//..
List<Notification> notifList = new ArrayList<>();
List<AcceptedInvitation> acceptedInvitations = new ArrayList<>();
Context context;
LayoutInflater inflater;

public NotificationAdapter(Context context){
    this.context = context;
    inflater = LayoutInflater.from(context);
}

public void addNotification(Notification notification){
    notifList.add(notification);
    notifyDataSetChanged();
    notifyItemInserted(notifList.size());
}

public void addAcceptedInvitation(AcceptedInvitation invitation){
    acceptedInvitations.add(invitation);
    notifyDataSetChanged();
    notifyItemInserted(acceptedInvitations.size());
}

@Override
public NotificationViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = inflater.inflate(R.layout.rv_notifications, parent, false);

    NotificationViewHolder holder = new NotificationViewHolder(view);

    return holder;
}

@Override
public void onBindViewHolder(final NotificationViewHolder holder, int position) {
    String user1= null;
    String user2= null;

    if(position < notifList.size()){

        user1= notifList.get(position).getUserName();

    }else {
        user2= acceptedInvitations.get(position).getUserName();

    }


@Override
public int getItemCount() {
    return notifList.size() + acceptedInvitations.size();
}
}

RecyclerView ViewHolder

public class NotificationViewHolder extends RecyclerView.ViewHolder {
//..  
TextView userName;

public NotificationViewHolder(View itemView) {
    super(itemView);

    userName = (TextView) itemView.findViewById(R.id.display_name);   
}
}

我在 onBindViewHolder() 部分有错误。顺便说一下,我正在使用 Firebase 检索数据。

Main Activity(在Activity启动时调用loadData())

 public void loadData(){
    //..
    final FirebaseDatabase database = FirebaseDatabase.getInstance();
    DatabaseReference ref = database.getReference().child("users").child(key).child("invitations");

    ref.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
            Notification notification = dataSnapshot.getValue(Notification.class);
            adapter.addNotification(notification);
       }

        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {

        }

        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });


    DatabaseReference invitationRef = database.getReference().child("users").child(key).child("acceptedInvitations");
    invitationRef.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
            AcceptedInvitation acceptedInvitation = dataSnapshot.getValue(AcceptedInvitation.class);
            Toast.makeText(getActivity(), dataSnapshot.getValue().toString(), Toast.LENGTH_LONG).show();
            adapter.addAcceptedInvitation(acceptedInvitation);

        }

        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {

        }

        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
}

我已经可以从invitations 和acceptedInvitations json-array 中检索数据,但是当我尝试从acceptedInvitations 填充数据时出现错误,基本上是在我调用“addAcceptedInvitation(acceptedInvitation)”时。
错误。

threadid=1:线程以未捕获的异常退出(组=0x41a81c80)

【问题讨论】:

  • 错误是什么?
  • 最大的错误风险是在user2= acceptedInvitations.get(position).getUserName(); 这一行中,并且在您的acceptedInvitationsposition 具有价值之前,可能会调用此行。请编辑您的问题,提及您调用 addNotificationaddAcceptedInvitation 的代码,如果它们的数据来自 Firebase,请在您调用 Firebase 的位置提供编码
  • 感谢您的回答。我已经编辑了我的问题。
  • 尝试将if(position &lt; notifList.size()){ ... } else { .. } 中的else 替换为.. } else if (position &lt; acceptedInvitations.size()) { ... }。它应该使您的错误消失。 (并在您回复我时提及我:D)
  • 错误消失了,但是recyclerview中没有填充数据。 @koceeng​​span>

标签: android firebase firebase-realtime-database


【解决方案1】:

我假设您想要合并 Notification 数据和 AcceptedInvitation 数据。请注意,当您调用两个 Firebase 数据库调用时,第二个将在第一个完成后执行。所以使用下面这段代码是可以的(因为如果没有,这段代码是有风险的)。

首先,删除addNotificationaddAcceptedInvitation中的notifyItemInserted(),因为如果在notifyDataSetChanged()之后直接调用它是没有用的。但如果您更喜欢保留notifyItemInserted() 而删除notifyDataSetChanged(),那就更复杂了。

然后让我们指出哪里出了问题。当您调用notifyDataSetChanged() 时,您的适配器将刷新其所有项目。在您的getItemCount() 中,您提到您的适配器有(notifList.size() + acceptedInvitations.size())。因此,如果您有 3 个notifList 和 2 个acceptedInvitations,您的适配器将从其第一个值刷新到 (3+2) 第五个值。

知道,onBindViewHolder 将被调用,position 值从 0 到 4(0 是第一个,4 是第五个)。看代码:

@Override
public void onBindViewHolder(final NotificationViewHolder holder, int position) {
    ...
    if(position < notifList.size()){
        user1 = notifList.get(position).getUserName();

    } else {
        user2 = acceptedInvitations.get(position).getUserName();
    }
}

请注意,当position 为0 或1 或2 时,这很好,因为它在这些索引上执行notifList.get(position)notifList 是存在的。但是当 position 为 3 时,它执行 acceptedInvitations.get(position) 会触发错误,因为 acceptedInvitations 仅在索引 0 和 1 上具有值,而不在 3 中

理解之后,你的代码应该是这样的:

@Override
public void onBindViewHolder(final NotificationViewHolder holder, int position) {
    ...
    if(position < notifList.size()){
        user1 = notifList.get(position).getUserName();

    } else {
        user2 = acceptedInvitations.get(position - notifList.size()).getUserName();
    }
}

希望有帮助:)

【讨论】:

  • 我遇到了一种情况,我必须用两个以上的列表填充适配器。我试图添加此代码 user2 = acceptedInvitations.get(position - listA.size() + listB.size()).getUserName(); 但它不会工作。顺便说一下,我有 3 个列表。
  • 如果你有3个列表,当然代码会有所不同。我已经在我的答案中包含了我提出该代码的逻辑。如果您仔细阅读并理解它并且您的代码逻辑仍然相同,那么user2 = acceptedInvitations.get(position - listA.size() + listB.size() + listC.size()).getUserName(); 将起作用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-14
  • 2017-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多