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
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
class ViewHolder0 extends RecyclerView.ViewHolder {
...
public ViewHolder0(View itemView){
...
}
}
class ViewHolder2 extends RecyclerView.ViewHolder {
...
public ViewHolder2(View itemView){
...
}
@Override
public int getItemViewType(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 contiguous
return position % 2 * 2;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case 0: return new ViewHolder0(...);
case 2: return new ViewHolder2(...);
...
}
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
switch (holder.getItemViewType()) {
case 0:
ViewHolder0 viewHolder0 = (ViewHolder0)holder;
...
break;
case 2:
ViewHolder2 viewHolder2 = (ViewHolder2)holder;
...
break;
}
}
}
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<RecyclerView.ViewHolder> {
final int VIEW_TYPE_MESSAGE = 0;
final int VIEW_TYPE_IMAGE = 1;
Context context;
List<ChatWrapper> messages;
List<ImageDataWrapper> images;
public ChatAdapter(Context context, List<ChatWrapper> messages, List<ImageDataWrapper> 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<ChatWrapper> messages;
List<ImageDataWrapper> 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:
valType
variable, getItemCount()
should always return the size of both lists combined, etc.)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
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.