1

I have got a situation.I am making chat application, on that I have one sender side and one receiver side. All the chats is shown in a List View individual rows.On get view lets suppose I have 5 sender messges and 5 receiver messages (including images) how will I handle the case.For sending side I have a layout (I am inflating using holder view pattern) it contains progress bar to show status image uploading on the other hand I am inflating another layout but on that I don't have any progress bar.In this case How recyles works?I mean last item(10th item visible to screen) is image that belongs to reciver side and it has no progress bar but as soon as scroll for 11th item recyle works and 11 th item is from sender side and it contains progress bar.Further more for system messages there is a third layout (to show status today,yesterday) and this third alot has just single text view what would happen when it gets reccyle for that item that contains image(when this layout does not have any image view) Should I use single row for all this and show/hide accordin to data Or is there any better approach available?

Abdul Waheed
  • 4,540
  • 6
  • 35
  • 58

2 Answers2

1

You can create a type field in your model class and inflate your View according to this type only.

your getView method will look like this:

           if (convertView == null) {
                if (model.getType() == 0) {
                    convertView = mInflater.inflate(R.layout.row_sent_message,
                            null);
                } else if (model.getView() == 1) {
                    convertView = mInflater.inflate(R.layout.row_sent_message,
                            null);
                } else if (model.getView() == 2) {
                    convertView = mInflater.inflate(R.layout.row_other, null);
                }
                holder = new ViewHolder(convertView);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }

And your ViewHolder Class should be like this:

private class ViewHolder {


        public ViewHolder(View rowView, int rowType) {
            // TODO Auto-generated constructor stub

            // According to your rowType find id of your view here 

        }
    }
Anjali
  • 1
  • 1
  • 13
  • 20
1

You need to use

getViewTypeCount()- Returns the number of types of Views that will be created by getView(int, View, ViewGroup).

getItemViewType(int position) - Get the type of View that will be created by getView(int, View, ViewGroup) for the specified item.

@Override
public int getItemViewType(int pos) {
    return pos % 2;
}

@Override
public int getViewTypeCount() {
    return 2; 
}

Then update getView to handle 2 types of layouts

public View getView(int pos, View convertView, ViewGroup parent) {
    ..............................................................
    ..............................................................
    if (convertView == null) {
        inflater = (LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE);
        if (getItemViewType(pos) == 0) {
            convertView = inflater.inflate(R.layout.layout_type_one, null);
        } else {
            convertView = inflater.inflate(R.layout.layout_type_two, null);
        }
        ..............................................................
        ..............................................................

    }
    ...................................................................
    ...................................................................
} 
human123
  • 295
  • 1
  • 9
  • "pos" is the position of item within adapter's data set. The above code is written assuming that you need 2 different types of rows. So we calculate remainder of current position when divided by 2 (which will always be 0 or 1. Hope you have seen that getItemViewType method is called in getView) so that we can choose from 2 different types of layouts. If you need more than 2, try adjusting value 2 to the value you require in both getItemViewType and getViewTypeCount. – human123 Nov 23 '15 at 12:38
  • yes, I got it now.It means If I need 3 different layout then getViewTypeCount() will return 3 and pos % 3 from getItemViewType(int pos) ? – Abdul Waheed Nov 23 '15 at 13:17
  • One more question I have let's suppose I have 10 items visible (because 10 items can be displayed at a time) on the screen and all belong to same layout (one layout) and for all those items convert view would be null but as soon as I scroll down for 11th or 12th item convert view will not be null,right? and now 11 or 12th item is on the screen visible but the 12th item belongs to second layout in this case what will happen? – Abdul Waheed Nov 23 '15 at 13:30
  • Yes. If you need 3 different layouts you need to do as you mentioned. For your new question, getItemViewType is an adapter method. Adapter will consider the value returned from this method to decide whether to use recycled views or not. So multiple types of views will be handled by adapter itself. Please also refer to accepted answer in https://stackoverflow.com/questions/5300962/getviewtypecount-and-getitemviewtype-methods-of-arrayadapter. Detailed explanation of flow of adapter handling of views is explained there. – human123 Nov 24 '15 at 07:45