I want to make a view where I can select multiple items from listview and also side by side am changing the color of selected list item and saving that item into my arraylis
The issue here is that you are setting the background color to the view, then when you scroll, you end up reusing that view due to using convertView
. This is exactly what you should be doing, so good job there.
But, of course, that means list items are selected when they shouldn't be. In order to fix this, your getView()
method needs to reset the background color to its default value. I don't know what the color was originally, but I'll assume it was transparent. So you would put:
textView.setBackgroundColor(android.R.color.transparent);
So now you're setting the background color to its default, but if you scroll away from the selected item, then back to it, it will have a transparent background instead of the selected background. To resolve this, put an ArrayList
of Integer
values inside your adapter class. When an item is clicked and onItemClick()
is triggered, add the item position to that ArrayList
. For example, say you have:
public ArrayList<Integer> selectedIds = new ArrayList<Integer>();
in your adapter class. Then, your onItemClick
method would look like this:
@Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
ArrayList<Integer> selectedIds = ((ItemsAdapter) parent).selectedIds;
Integer pos = new Integer(position);
if(selectedIds.contains(pos) {
selectedIds.remove(pos);
}
else {
selectedIds.add(pos);
}
parent.notifyDataChanged();
}
So, finally, in your getView()
method, add this line:
textView.setBackground(selectedIds.contains(position) ? R.color.result_image_border : androi.R.color.transparent);
You have to set flag when you click any list item from the list and check this flag to determine weather the item has been clicked or not in you getView() method of the adapter.
The solution (idea) from Jason Robinson is good, but there is an error! You can not remove item from ArrayList by it's value!!!
Method ArrayList.remove(int) takes item's index as parametr!
If you want to use an ArrayList<
, you need to find index ot item you want to remove. For example:Integer
>
private int getIndex(int value) {
int index = -1;
for(int i=0; i<selectedIds.size(); i++) {
if(selectedIds.get(i)==value) {
index = i;
break;
}
}
return index;
}
Or use method ArrayList.indexOf(Object)
to obtain index.
And now, how to get reference to your adapter from FragmenList or ListActivity. Simply use class variable:
public class SimpleFragment extends ListFragment {
private MyCustomAdapter mAdapter;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mAdapter = new MyCustomAdapter(getActivity(), R.layout.row_layout);
setListAdapter(mAdapter);
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
// now you have an access to your adapter through class variable mAdapter
}
}
Keep track of the items selected in the listView in the Activity. In the getView of the adapter check if position equals selected position in the listview and setBackgroundColor for the view there. This will work.
Whatever you try to do with ConvertView in itemClick listener it will reflect in some other class, to avoid that you need to set the background for corresponding view holder , i show up some sample which works fine for me,
public View getView(final int position, View convertView, ViewGroup parent) {
System.gc();
final ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.albumlist, null);
holder = new ViewHolder();
holder.albumName = (TextView) convertView.findViewById(R.id.albumDetails);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
holder.albumName.setText(albumData[position][0]);
holder.albumName.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
holder.albumName.setBackgroundColor(R.color.black);
}});
return convertView;
}
class ViewHolder {
TextView albumName;
}
sample o/p
I have also encountered this problem, and found out that it is because recycling views. If i remember right setting this removes recycling and fixes the problem, but it's not the best option here.
@Override
public int getItemViewType(int position) {
return IGNORE_ITEM_VIEW_TYPE;
}