I did my custom ArrayAdapter to highlight the selected item of a ListView.
The code is as following:
public class HeroListViewAdapter extends ArrayAdapter<Hero> {
public static int NO_POS = -1;
private List<Hero> heroes;
private int selected_pos = NO_POS;
public HeroListViewAdapter(Context context, List<Hero> heroes){
super(context, R.layout.hero_list_item_view, heroes);
this.heroes = heroes;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = GuiBuilder.createHeroListItemView(heroes.get(position),getContext(),parent,false);
if(position == selected_pos){
rowView.setBackgroundColor((rowView.getResources().getColor(R.color.list_item_selected_color)));
}
return rowView;
}
public void setSelectedPosition(int selected_pos){
this.selected_pos = selected_pos;
}
public int getSelectedPosition(){
return selected_pos;
}
public Hero getSelectedHero(){
if(selected_pos>=0 && selected_pos<heroes.size())
return this.getItem(selected_pos);
else
return null;
}
}
where the methods modify an inner member to keep track of the selected position and the getView method test the value of this inner member in order to highlight the item by changing his background. Things are used in the following way:
listView.setOnItemClickListener(new AdapterView.OnItemClickListener(){
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
list_adapter.setSelectedPosition(position);
listView.invalidate();
}
});
Now…everything works fine as intended on my 2.2.1 Froyo (level API 8) smartphone. But running the application on the emulator (level API 16) when I click an item the background doesn’t change.
So the question is: is this an API issue (and backward compatibility?) or an emulator one? Do I have to worry about that the application may not work as intended on other devices than mine.
The fact that it works on smartphone is a pure luck. This isn’t intended to work.
listView.invalidate()just isn’t enough. You should callnotifyDataSetChanged()in you adapter afterlist_adapter.setSelectedPosition(position)call.invalidate()just redraws a view. Adapter’sgetView()is called during list view layout run (not draw run) and it isgetView()where you change background.Also you can call listView.requestLayout() instead of listView.invalidate(). It’s ugly but it should work.