2017-01-10 2 views
1

У меня есть два arraylist, и я хочу отображать данные в обоих списках в том же recyclerview. Мой код выглядит так.Заполняют один пользовательский адаптер с двумя списками массивов в 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-массив, но у меня есть ошибка, когда я попытался заполнить данные из принятыхInvitations, в основном, когда я называю addAcceptedInvitation (acceptInvitation) ".
Ошибка.

ThreadId = 1: поток, выходящий с неперехваченного исключением (группа = 0x41a81c80)

+0

Какая ошибка? –

+0

Наибольший риск при ошибке находится в этой строке 'user2 = acceptedInvitations.get (position) .getUserName();' и эта строка, вероятно, вызывается до того, как ваши 'acceptInvitations' будут иметь значение в' position'.Пожалуйста, отредактируйте свой вопрос, указав код, который вы называете 'addNotification' и' addAcceptedInvitation', и если их данные из Firebase, пожалуйста, укажите кодировку, где вы вызываете Firebase – koceeng

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

Надежда это help :)

+0

Я столкнулся с случаем, который мне придется заполнить адаптером более чем двумя списками , Я попытался добавить этот код ** user2 = acceptedInvitations.get (position - listA.size() + listB.size()). GetUserName(); ** Но это не сработает. Кстати, у меня есть 3 списка. –

+0

если у вас 3 списка, то, конечно, код будет другим. Я включил логику, почему я придумал этот код в своем ответе. Если вы внимательно прочитаете его и поймете, И если ваша логика кода остается прежней, тогда 'user2 = acceptInvitations.get (position - listA.size() + listB.size() + listC.size()). GetUserName(); 'будет работать – koceeng

Смежные вопросы