Reputation: 85
I am building an Android app, and as part of it I am displaying a list on songs with checkboxes to allow for selection. I am using a custom list adapter to do this. The code seems to load and works with the checkboxes, but the only problem I am having is that only the very top item in the listview shows the text until I scroll down the list, then the other items render the text.
I am aware that it might be a problem with the listview not refreshing or something like that but I can't figure out how to fix it.
Heres the code for my adapter:
private class PlaylistDetailsAdapter extends ArrayAdapter<Song> {
boolean[] checkBoxState;
ViewHolder viewHolder;
public PlaylistDetailsAdapter(Context context, int textViewResourceId, ArrayList<Song> songs) {
super(context, textViewResourceId, songs);
checkBoxState = new boolean[songs.size()];
}
private class ViewHolder {
TextView songName;
CheckBox checkBox;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.activity_playlist_details_row, null);
viewHolder = new ViewHolder();
viewHolder.songName = (TextView)convertView.findViewById(R.id.playlist_details_song_name);
viewHolder.checkBox = (CheckBox)convertView.findViewById(R.id.playlist_details_checkbox);
convertView.setTag(viewHolder);
}
else {
viewHolder = (ViewHolder)convertView.getTag();
Song song = playlistSongs.get(position);
viewHolder.songName.setText(song.getTitle() + " - " + song.getArtist());
viewHolder.checkBox.setChecked(checkBoxState[position]);
viewHolder.checkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (((CheckBox)v).isChecked()) {
checkBoxState[position] = true;
}
else {
checkBoxState[position] = false;
}
}
});
}
return convertView;
}
}
This is the code to set up the list view:
playlistSongs = db.getPlaylistTracks(getIntent().getLongExtra("id", 0));
TextView playlistName = (TextView)findViewById(R.id.playlist_details_name);
playlistName.setText(getIntent().getStringExtra("name"));
final PlaylistDetailsAdapter adapter = new PlaylistDetailsAdapter(this, R.layout.activity_playlist_details_row, playlistSongs);
ListView playlistSongList = (ListView)findViewById(R.id.listview_playlist_details);
playlistSongList.setAdapter(adapter);
Any help would be greatly appreciated.
Thanks
Upvotes: 3
Views: 6301
Reputation: 2274
Hi friend you can use horizontal or vertical scroll view to remove this problem as you know that list-view is recycled every time.
I am also faced this problem before than i use scroll in comparison to listview
then create a Boolean arrayList of as the size of your list item and set all the value false first. after that u can use your code
@Override
public void onClick(View v) {
if (((CheckBox)v).isChecked()) {
checkBoxState[position] = true;
}
else {
checkBoxState[position] = false;
}
}
});
Upvotes: 0
Reputation: 116332
The problem is that you don't put the data into the views when the convertView==null , You only set how to find them .
What you need to do is to remove from the "else" part , the code that actually change the views , and put it right after the whole if-else area .
example :
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
...
}
else
viewHolder = (ViewHolder)convertView.getTag();
// now we have the views ready to be changed , so change them :
Song song = playlistSongs.get(position);
...
return convertView;
}
Upvotes: 5
Reputation: 1039
call:
adapter.notifyDataSetChanged()
when your list contains new data
Upvotes: 0