在recyclerview中使用两个数组列表填充一个自定义适配器

时间:2017-01-10 03:02:07

标签: android firebase firebase-realtime-database

我有两个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来检索数据。

主要活动(活动开始时调用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) {

        }
    });
}

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

  

threadid = 1:线程退出,未捕获异常(group = 0x41a81c80)

1 个答案:

答案 0 :(得分:0)

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

首先,删除notifyItemInserted()addNotification内的addAcceptedInvitation,因为如果在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();
    }
}

希望这有帮助:)