I get duplicated items in a ListView. Scrolling back and down sometimes changes the item order. I googled and found many threads reporting this bug, but none of them helped me in fixing my issue.
Here is my code:
Activity:
package com.github.progval.SeenDroid;
import java.util.ArrayList;
import java.util.List;
import com.github.progval.SeenDroid.lib.Connection;
import com.github.progval.SeenDroid.lib.Message;
import com.github.progval.SeenDroid.lib.MessageFetcher;
import com.github.progval.SeenDroid.lib.Query.ParserException;
import android.app.Activity;
import android.app.ListActivity;
import android.content.SharedPreferences;
import android.os.Bundle;
public class ShowUserActivity extends ListActivity {
private Connection connection;
public ArrayList<Message> listMessages = new ArrayList<Message>();
public MessageAdapter adapter;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.profile);
this.connection = new Connection();
this.setTitle(R.string.homefeed_title);
this.listMessages = new MessageFetcher(this.connection).fetchUser();
this.bindUi();
}
private void bindUi() {
this.adapter = new MessageAdapter(this, this.listMessages);
this.setListAdapter(adapter);
// TODO Bind buttons
}
}
MessageAdapter:
package com.github.progval.SeenDroid;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.Inflater;
import com.github.progval.SeenDroid.lib.Message;
import android.content.Context;
import android.text.Layout;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MessageAdapter extends BaseAdapter {
private Context context;
private List<Message> items = new ArrayList<Message>();
private int lastPosition = 0;
public MessageAdapter(Context context, List<Message> items) {
super();
this.context = context;
this.items = items;
}
public View getView(int position, View convertView, ViewGroup parent) {
if (null == convertView) {
LinearLayout view;
view = (LinearLayout) LinearLayout.inflate(this.context, R.layout.message, null);
Log.d("SeenDroid", String.format("Get view %d", position));
TextView title = new TextView(view.getContext());
title.setText(this.items.get(position).getTitle());
view.addView(title);
return view;
} else {
return convertView;
}
}
@Override
public int getCount() {
return this.items.size();
}
@Override
public Object getItem(int location) {
return this.items.get(location);
}
@Override
public long getItemId(int arg0) {
return arg0;
}
}
By the way, the output is:
D/SeenDroid(30939): Get view 0
D/SeenDroid(30939): Get view 1
D/SeenDroid(30939): Get view 2
D/SeenDroid(30939): Get view 3
D/SeenDroid(30939): Get view 4
D/SeenDroid(30939): Get view 5
D/SeenDroid(30939): Get view 6
D/SeenDroid(30939): Get view 7
D/SeenDroid(30939): Get view 8
D/SeenDroid(30939): Get view 0
D/SeenDroid(30939): Get view 16
Regards, ProgVal
Try this:
public View getView(int position, View convertView, ViewGroup parent) {
if (null == convertView) {
LinearLayout view = (LinearLayout) LinearLayout.inflate(this.context,
R.layout.message, null);
Log.d("SeenDroid", String.format("Get view %d", position));
TextView title = new TextView(view.getContext());
title.setText(this.items.get(position).getTitle());
view.addView(title);
return view;
} else {
LinearLayout view = (LinearLayout) convertView;
TextView title = (TextView) view.getChildAt(0);
title.setText(this.items.get(position).getTitle());
return convertView;
}
}
Explanation: you got the duplicates because lists on Android reuse UI objects. You are expected to reuse convertView
rather than create a new one if it is not null. Of course, you are responsible to set an appropriate value to the instance being reused. Otherwise the value is left from the last "usage".
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridView;
if (convertView == null) {
gridView = new View(context);
} else {
gridView = (View) convertView;
}
gridView = inflater.inflate(R.layout.worker_listmain, null);
// your source code here!!! Run 100%
// I got this problem also, I found out the way to solve it!
// Please use my source code :D SIMPLE is PERFECT :D
return gridView;
}
ListView does not guarantee uniqueness of items you are added there. It is your responsibility. You are using ArrayList
to store items and it can store as many duplicate items as you want.
If you want to removed duplicates put your items into set and then into list again:
listMessages = new ArrayList<Messages>(new LinkedHashSet<Message>(listMessages))
The LinkedHashSet
will remove duplicates preserving the initial order of items, ArrayList
will allow access elements by position.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With