Skip to content Skip to sidebar Skip to footer

Two Arraylist One Recyclerview Adapter

I have a chat screen where i can chat with other user, i am sending chat data (message,time and sender via List) to RecyclerAdapter which populate chat views with data.Now i have o

Solution 1:

It sounds like you want to show two different lists of items in the same RecyclerView using the same RecyclerView.Adapter. Thankfully, this is the kind of thing RecyclerView.Adapter can handle really nicely.

Here's how your RecyclerView.Adapter should look:

publicclassChatAdapterextendsRecyclerView.Adapter<RecyclerView.ViewHolder> {
    finalintVIEW_TYPE_MESSAGE=0;
    finalintVIEW_TYPE_IMAGE=1;

    Context context;
    List<ChatWrapper> messages;
    List<ImageDataWrapper> images;

    publicChatAdapter(Context context, List<ChatWrapper> messages, List<ImageDataWrapper> images){
        this.context = context;
        this.messages = messages;
        this.images = images;
    }

    @Overridepublic RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
        if(viewType == VIEW_TYPE_MESSAGE){
            returnnewMessageViewHolder(itemView);
        }

        if(viewType == VIEW_TYPE_IMAGE){
            returnnewImageViewHolder(itemView);
        }

        returnnull;
    }

    @OverridepublicvoidonBindViewHolder(RecyclerView.ViewHolder viewHolder, int position){
        if(viewHolder instanceof MessageViewHolder){
            ((MessageViewHolder) viewHolder).populate(messages.get(position));
        }

        if(viewHolder instanceof ImageViewHolder){
            ((ImageViewHolder) viewHolder).populate(images.get(position - messages.size()));
        }
    }

    @OverridepublicintgetItemCount(){
        return messages.size() + images.size();
    }

    @OverridepublicintgetItemViewType(int position){
        if(position < messages.size()){
            return VIEW_TYPE_MESSAGE;
        }

        if(position - messages.size() < images.size()){
            return VIEW_TYPE_IMAGE;
        }

        return -1;
    }

    publicclassMessageViewHolderextendsRecyclerView.ViewHolder {
        TextView message;
        TextView timeStamp;
        ImageView userImage;

        publicMessageViewHolder(View itemView){
            super(itemView);

            message = (TextView) itemView.findViewById(R.id.Single_Item_Chat_Message);
            timeStamp = (TextView) itemView.findViewById(R.id.Single_Item_Chat_TimeStamp);
            userImage = (ImageView) itemView.findViewById(R.id.Single_Item_Chat_ImageView);
        }

        publicvoidpopulate(ChatWrapper chatWrapper){
            message.setText(chatWrapper.getMessage());
            userImage.setText(chatWrapper.getTimestamp());
        }
    }

    publicclassImageViewHolderextendsRecyclerView.ViewHolder {
        TextView dataTitle;
        TextView dataLink;
        TextView dataSnippet;
        ImageView image;
        ImageButton dataSendButton;

        publicImageViewHolder(View itemView){
            super(itemView);

            dataTitle = (TextView) itemView.findViewById(R.id.Image_data_Title);
            dataLink = (TextView) itemView.findViewById(R.id.Image_data_Link);
            dataSnippet = (TextView) itemView.findViewById(R.id.Image_data_Snippet);
            image = (ImageView) itemView.findViewById(R.id.Image_data_Image);
            dataSendButton = (ImageButton) itemView.findViewById(R.id.Image_data_SendButton);
        }

        publicvoidpopulate(ImageDataWrapper imageDataWrapper){
            dataTitle.setText(imageDataWrapper.getPage_Title());
            dataLink.setText(imageDataWrapper.getPage_Link());
            dataSnippet.setText(imageDataWrapper.getPage_Desc());
            Picasso.with(context).load(imageDataWrapper.getPage_ImageThumb()).into(image);
        }
    }
}

Here's what your Activity is going to need:

List<ChatWrapper> messages;
List<ImageDataWrapper> images;
ChatAdapter adapter;

@OverridepublicvoidonCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);

    messages = newArrayList<>();
    images = newArrayList<>();
    ChatAdapter adapter = newChatAdapter(this, messages, images);

    RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
    recyclerView.setLayoutManager(newLinearLayoutManager(this));
    recyclerView.setAdapter(adapter);
}

publicvoidaddMessage(ChatWrapper message){
    messages.add(message);
    adapter.notifyDataSetChanged();
}

publicvoidremoveMessage(ChatWrapper message){
    if(messages.remove(message)){
        adapter.notifyDataSetChanged();
    }
}

publicvoidaddImage(ImageDataWrapper image){
    images.add(image);
    adapter.notifyDataSetChanged();
}

publicvoidremoveImage(ImageDataWrapper image){
    if(images.remove(image)){
        adapter.notifyDataSetChanged();
    }
}

When you want to update the data, just call addMessage(ChatWrapper) or removeMessage(ChatWrapper) for messages and addImage(ImageDataWrapper) or removeImage(ImageDataWrapper) for images.

Some key points:

  • You don't want to create any new Adapters or Lists, you simply want to call methods on our existing objects.
  • Your Adapter should behave as if it always has to deal with messages and images, but just that it can handle 0 messages or 0 images (no valType variable, getItemCount() should always return the size of both lists combined, etc.)

Solution 2:

First you need to combine both array in single arraylist like.. firsArrlist.addAll(secondArrList);

and pass into recyclerview adapter and migrate with some flag and take another viewholder for particular flag to set that view in recyclerview.

And total count is must both firstArrlist.size + secondArrList.size

Solution 3:

publicclassMyAdapterextendsRecyclerView.Adapter<RecyclerView.ViewHolder> {
classViewHolder0extendsRecyclerView.ViewHolder {
    ...
    publicViewHolder0(View itemView){
    ...
    }
}

classViewHolder2extendsRecyclerView.ViewHolder {
    ...
    publicViewHolder2(View itemView){
    ...
}

@OverridepublicintgetItemViewType(int position) {
    // Just as an example, return 0 or 2 depending on position// Note that unlike in ListView adapters, types don't have to be contiguousreturn position % 2 * 2;
}

@Overridepublic RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
     switch (viewType) {
         case0: returnnewViewHolder0(...);
         case2: returnnewViewHolder2(...);
         ...
     }
}

@OverridepublicvoidonBindViewHolder(final RecyclerView.ViewHolder holder, finalint position) {
    switch (holder.getItemViewType()) {
        case0:
            ViewHolder0viewHolder0= (ViewHolder0)holder;
            ...
            break;

        case2:
            ViewHolder2viewHolder2= (ViewHolder2)holder;
            ...
            break;
    }
}

}

Solution 4:

I had your same problem. You can create a Pojo class if you need and enter the association for example a chat can have multiple images. Then build the chat object and insert a list of images in it. Before passing the list to the adapter, populate it with the original data. I know this may not be a nice solution for your needs, but remember that you can have full control, without segmenting the lists.

Post a Comment for "Two Arraylist One Recyclerview Adapter"