I've set a BaseAdapter to the ListView in my Android app. Every time I click on the ListView the click actions work fine. But the element I click always goes to the top of the ListView.
How do I make the clicked item keep its place when I click on the ListView?
Could this problem be due to BaseAdapter?
public class TrackAdapter extends BaseAdapter {
private final Context context;
private List<Track> tracks;
public TrackAdapter(List<Track> tracks, Context context) {
this.tracks = tracks;
this.context = context;
}
@Override
public int getCount() {
return tracks.size();
}
@Override
public Object getItem(int position) {
return tracks.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
public void updateAdapter(List<Track> list) {
tracks = list;
this.notifyDataSetChanged();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = LayoutInflater.from(context).inflate(R.layout.track_list_layout, parent, false);
convertView.setBackgroundResource(R.drawable.listview_background);
TextView name = convertView.findViewById(R.id.track_name);
name.setText(tracks.get(position).getName());
TextView bpm = convertView.findViewById(R.id.track_bpm);
bpm.setText(BPMHelper.Combine(tracks.get(position).getMinBpm(), tracks.get(position).getMaxBpm()));
TextView type = convertView.findViewById(R.id.track_type);
type.setText(tracks.get(position).getType());
TextView size = convertView.findViewById(R.id.track_size);
size.setText(tracks.get(position).getSize());
return convertView;
}
}
And
trackList = (ListView) findViewById(R.id.listView);
trackList.setAdapter(trackAdapter);
trackList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
// @SuppressLint("ResourceAsColor")
TextView previousView = null; // to hold the previous clicked view
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView textView = view.findViewById(R.id.track_name);
if (previousView != null) {
// revert the previous view when a new item is clicked
previousView.setTextColor(Color.YELLOW);
}
previousView = textView;
textView.setTextColor(Color.RED);
}
});
My ListView in CoordinatorLayout
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="587dp"
android:layout_margin="10dp"
android:divider="@color/grey"
android:dividerHeight="10.0sp"
android:scrollbars="none" />
at first: read how recycling pattern works, understaing this is crucial in here. do NOT inflate new
convertViewbyconvertView = LayoutInflater.from(context)...lineafter that: you very should NOT change
Views insideonItemClick, adapter is responsible for that, so you should inform it that some item should be drawn with different color:now you need
setLastPickedItemmethod inside your adapter, which will store this position for further use (when redraw occurs)after calling
notifyDataSetChangedadapter will eventually call againgetViewmethod for every visibleposition, so in here you should check is currently being drawn item atpostionis flagged as lastly presseddue to recycling pattern ALWAYS draw whole current state (in your case always set text color), as previously drawn item (recycled) may be in any other state and its look may stay
if you want to keep some history of previously clicked items then just adjust
setLastPickedItemmethod, store previously clicked in another variable (or array of all clicked) and don't forget to check and draw this state ingetView