I watched, I looked in the direction of RecyclerView and finally decided to throw a ListView on you too!

In the bad past, my ListView used for two layouts. Now I repeated it, but missed something. The point is this: markup two, one for the right message (yours), the other for the left message (someone else's). So, the left messages as it was posted correctly. The right "moved" and now everything is on the left. And the right vedas should be on the right! Moreover, the messages I have are decorated in different ways and everything looks as expected, but everything is on the left!

Here is my adapter code. The first code for RecyclerView :)

 public class RVAdapter extends RecyclerView.Adapter<MainActivity.RVAdapter.AdapterHolder> { public class AdapterHolder extends RecyclerView.ViewHolder { TextView tv_full_author, tv_circle_author, tv_client, tv_text, tv_data; AdapterHolder(View itemView) { super(itemView); tv_full_author = (TextView)itemView.findViewById(R.id.full_nick); tv_circle_author = (TextView)itemView.findViewById(R.id.first_char_nick); tv_client = (TextView)itemView.findViewById(R.id.reply_marker); tv_text = (TextView)itemView.findViewById(R.id.message); tv_data = (TextView)itemView.findViewById(R.id.time); } } ArrayList<HashMap<String, String>> adapterList; int type; RVAdapter(ArrayList<HashMap<String, String>> dat){ adapterList = dat; } @Override public void onAttachedToRecyclerView(RecyclerView recyclerView) { super.onAttachedToRecyclerView(recyclerView); } @Override public AdapterHolder onCreateViewHolder(ViewGroup viewGroup, int i) { View v = LayoutInflater.from(viewGroup.getContext()).inflate(((i==0)? R.layout.item_right: R.layout.item_left), null); AdapterHolder pvh = new AdapterHolder(v); return pvh; } @Override public void onBindViewHolder(AdapterHolder holder, int i) { HashMap<String,String> fast_parse = adapterList.get(i); String author_str = fast_parse.get("author"); String client_str = fast_parse.get("client"); String text_str = fast_parse.get("text"); String data_str = fast_parse.get("data"); holder.tv_full_author.setText(author_str); holder.tv_circle_author.setText(author_str.substring(0,1)); if(!client_str.equals("0")) { holder.tv_client.setVisibility(View.VISIBLE); holder.tv_client.setText(client_str+","); if(client_str.equals(nick)&&(getItemViewType(i)==1)) { holder.tv_client.setTextColor(Color.parseColor("#A40dff")); } else{ holder.tv_client.setTextColor(Color.BLACK); } } else{ holder.tv_client.setText(""); holder.tv_client.setVisibility(View.GONE); } holder.tv_text.setText(text_str); holder.tv_data.setText(data_str); } @Override public int getItemViewType(int position) { if (adapterList.get(position).get("author").equals(nick)) return 0; else return 1; } public int getItemViewTypeCount(){ return 2; } @Override public int getItemCount() { return adapterList.size(); } } 

There are suspicions that onCreateViewHolder() I somehow incorrectly create the view , although I take into account getItemViewType()

  • On the first question you can read here . - post_zeew
  • At first glance, everything seems to be correct. Confuses the line to create a View. It should be something like: View v = LayoutInflater.from(viewGroup.getContext()).inflate(((i==0)? R.layout.item_right: R.layout.item_left), viewGroup, false); . I would not use such constructions at all, but would split it into several lines with more distinct initialization logic. - pavlofff

1 answer 1

To implement two different types of list items you need:

  • Two ViewHolder 's
  • override the getItemViewType method
  • override onCreateViewHolder method
  • add a switch to onBindViewHolder in order to distinguish between different ViewHolder

Implementation:

  • create a ViewHolder 's

     public class ViewHolder1 extends RecyclerView.ViewHolder { private TextView label1, label2; public ViewHolder1(View v) { super(v); label1 = (TextView) v.findViewById(R.id.text1); label2 = (TextView) v.findViewById(R.id.text2); } } public class ViewHolder2 extends RecyclerView.ViewHolder { private ImageView ivExample; public ViewHolder2(View v) { super(v); ivExample = (ImageView) v.findViewById(R.id.ivExample); } } 
  • Override the getItemViewType method:

      @Override public int getItemViewType(int position) { if (items.get(position) instanceof User) { return USER; } else if (items.get(position) instanceof String) { return IMAGE; } return -1; } 
  • override the onCreateViewHolder method:

     @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { RecyclerView.ViewHolder viewHolder; LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext()); switch (viewType) { case USER: View v1 = inflater.inflate(R.layout.layout_viewholder1, viewGroup, false); viewHolder = new ViewHolder1(v1); break; case IMAGE: View v2 = inflater.inflate(R.layout.layout_viewholder2, viewGroup, false); viewHolder = new ViewHolder2(v2); break; default: View v = inflater.inflate(android.R.layout.simple_list_item_1, viewGroup, false); viewHolder = new RecyclerViewSimpleTextViewHolder(v); break; } return viewHolder; } 
  • determine what type of list item we got:

     @Override public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) { switch (viewHolder.getItemViewType()) { case USER: ViewHolder1 vh1 = (ViewHolder1) viewHolder; configureViewHolder1(vh1, position); break; case IMAGE: ViewHolder2 vh2 = (ViewHolder2) viewHolder; configureViewHolder2(vh2, position); break; default: RecyclerViewSimpleTextViewHolder vh = (RecyclerViewSimpleTextViewHolder) viewHolder; configureDefaultViewHolder(vh, position); break; } } 

Try to add yourself such an implementation, everything should work out!

  • Thanks, I already managed it myself, the thing was that I did not create the view as it should) - Flippy