Two ArrayList one RecyclerView Adapter

前端 未结 4 917
醉酒成梦
醉酒成梦 2020-12-03 15:55

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

4条回答
  •  攒了一身酷
    2020-12-03 16:24

    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:

    public class ChatAdapter extends RecyclerView.Adapter {
        final int VIEW_TYPE_MESSAGE = 0;
        final int VIEW_TYPE_IMAGE = 1;
    
        Context context;
        List messages;
        List images;
    
        public ChatAdapter(Context context, List messages, List images){
            this.context = context;
            this.messages = messages;
            this.images = images;
        }
    
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
            if(viewType == VIEW_TYPE_MESSAGE){
                return new MessageViewHolder(itemView);
            }
    
            if(viewType == VIEW_TYPE_IMAGE){
                return new ImageViewHolder(itemView);
            }
    
            return null;
        }
    
        @Override
        public void onBindViewHolder(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()));
            }
        }
    
        @Override
        public int getItemCount(){
            return messages.size() + images.size();
        }
    
        @Override
        public int getItemViewType(int position){
            if(position < messages.size()){
                return VIEW_TYPE_MESSAGE;
            }
    
            if(position - messages.size() < images.size()){
                return VIEW_TYPE_IMAGE;
            }
    
            return -1;
        }
    
        public class MessageViewHolder extends RecyclerView.ViewHolder {
            TextView message;
            TextView timeStamp;
            ImageView userImage;
    
            public MessageViewHolder(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);
            }
    
            public void populate(ChatWrapper chatWrapper){
                message.setText(chatWrapper.getMessage());
                userImage.setText(chatWrapper.getTimestamp());
            }
        }
    
        public class ImageViewHolder extends RecyclerView.ViewHolder {
            TextView dataTitle;
            TextView dataLink;
            TextView dataSnippet;
            ImageView image;
            ImageButton dataSendButton;
    
            public ImageViewHolder(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);
            }
    
            public void populate(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 messages;
    List images;
    ChatAdapter adapter;
    
    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
    
        messages = new ArrayList<>();
        images = new ArrayList<>();
        ChatAdapter adapter = new ChatAdapter(this, messages, images);
    
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setAdapter(adapter);
    }
    
    public void addMessage(ChatWrapper message){
        messages.add(message);
        adapter.notifyDataSetChanged();
    }
    
    public void removeMessage(ChatWrapper message){
        if(messages.remove(message)){
            adapter.notifyDataSetChanged();
        }
    }
    
    public void addImage(ImageDataWrapper image){
        images.add(image);
        adapter.notifyDataSetChanged();
    }
    
    public void removeImage(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.)

提交回复
热议问题