Listview in Arrayadapter Order Get's Mixed Up When Scrolling

ListView's contents scrambled on scroll

Yes your problem is related to the fact that List reuses the views for each row. So say your list can see 5 items, but your ListAdapter has 15 things in it. Android will create 5 + 1 instances of your row view instead of 15. One for each row in the list + 1 for when half of the top and bottom can be seen. When a row is moved out of the visible area the List will recycle that view instance for another row instead of creating a new one. If you don't properly reset all of the user interface components every time you'll get artifacts from other rows showing up. You must make sure that every time you bind your data from the objects in your array list to the view you set every field every time.

For a better description of this see

http://www.youtube.com/watch?v=N6YdwzAvwOA&feature=related

Android ListView Layouts get mixed up on scroll

Your convertView is probably being reused, you have to check when it is different that null, if it is the correct layout and reinflate the correct one.

You can add the layout id to the ViewHolder and check if the convertView is different than null, then inflate the correct layout if the id is different than the one you want.

Something like this:

@Override
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder holder = null;
if(convertView == null || ((ViewHolder)convertView.getTag()).id != this.items.get(position).getId())
{
LayoutInflater layoutInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if(this.items.get(position).getId() == this.id)
convertView = layoutInflater.inflate(R.layout.layout1);
else
convertView = layoutInflater.inflate(R.layout.layout2);
holder = new ViewHolder();
holder.textView1 = (TextView) convertView.findViewById(R.id.textViewItem1);
holder.textView2 = (TextView) convertView.findViewById(R.id.textViewItem2);
holder.id = this.items.get(position).getId();
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
holder.textView1.setText(this.items.get(position).getInfo1());
holder.textView2.setText(this.items.get(position).getInfo2());
return convertView;
}

public static class ViewHolder
{
public int id; //Assuming your id is an int, if not, changed it to the correct type
public TextView textView1;
public TextView textView2;
}

android listview displays false data after scrolling (custom adapter)

I had a similar problem with multiple item types in the list. In my case the list item was either a section (label) item or a common list item.

To work with such types of lists, you should override getViewTypeCount and getItemViewType methods.
Something like this:

private static final int ITEM_VIEW_TYPE_ITEM = 0;
private static final int ITEM_VIEW_TYPE_SEPARATOR = 1;

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

@Override
public int getItemViewType(int position) {
return this.getItem(position).isSection() ? ITEM_VIEW_TYPE_SEPARATOR : ITEM_VIEW_TYPE_ITEM;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
final Item item = this.getItem(position);

if (convertView == null) {
convertView = mInflater.inflate(item.isSection() ? R.view1 : R.view2, null);
}

if(item.isSection()){
//...
}
else{
//...
}

return convertView;
}

Then the convertView parameter will always be correct and contain that type which you need.

And another thing: you explicitly added the public Param[] params field when you already have it in the base class ArrayAdapter<Param>.

I would recommend to inherit from the BaseAdapter class.

Edit:
Here is the code which you can try to use in order to make your Spinner work:

sp.setTag(p);
sp.setOnItemSelectedListener(new OnItemSelectedListener(){
public void onItemSelected(AdapterView<?> parent, View convertView, int pos, long id) {
Param currentItem = (Param)parent.getTag();
currentItem.setDefData(currentItem.getData().get(pos));
currentItem.setChanged(true);
}
//...

Try to use the combination of the getTag and setTag methods. I remember that I had similar problems with event handlers and final variables, but I completely forgot the cause of them, so I can't explain exactly why this happens.

BaseAdapter causing ListView to go out of order when scrolled

You are only putting data in the TextView widgets when they are first created. You need to move these four lines:

        TextView label = (TextView)view.findViewById(R.id.groups_item_title);
label.setText(mContacts.get(position).getName());
label = (TextView)view.findViewById(R.id.groups_item_subtitle);
label.setText(mContacts.get(position).getNumber());

to be after the if/else block and before the method return, so you update the TextView widgets whether you are recycling the row or creating a fresh one.

ListView shows wrong items on Scroll

I think you have a problem here

    @Override
public View getView(int position, View convertView, ViewGroup parent) {

View clist;

LayoutInflater inflater = (LayoutInflater) cntxt.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {

clist = inflater.inflate(textviewres, null);
TextView tv = (TextView) clist.findViewById(R.id.textv);
tv.setText(client_list.get(position).getName());

} else {
clist = convertView;
}
return clist;

}

So when your convert view is not null you are not populating your list like this

     TextView tv = (TextView) clist.findViewById(R.id.textv);
tv.setText(client_list.get(position).getName());

I generally do something like this

     public class MyHolder {
TextView keyword, tweetCount;
public MyHolder(View v) {
keyword = (TextView) v.findViewById(R.id.keyword_text);
tweetCount = (TextView) v.findViewById(R.id.tweets_count_text);
}

}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
MyHolder holder;
if (view == null) {
view = LayoutInflater.from(mContext).inflate(R.layout.keyword_contents, parent, false);
holder = new MyHolder(view);
view.setTag(holder);
} else {
holder = (MyHolder) view.getTag();
}
holder.keyword.setText(list.get(position).getKeyword());
holder.tweetCount.setText(String.valueOf(list.get(position).getCount()));
return view;
}

I think what holder will do is instead of finding textview again and again it will only findviewbyid once



Related Topics



Leave a reply



Submit