Objective
I want to play sound on click of List item with ImageButton (initially hidden, visible on click) showing play pause (2 images) resource. ImageButton is only to show state of sound to user.
Problem
When I scroll the List, imageButton is again GONE.
Code
BaseAdapter
private class ListAdapter extends BaseAdapter {
private Context mContext;
private LayoutInflater mInflater;
ViewHolder holder;
ListAdapter(Context context) {
mContext = context;
this.mInflater = LayoutInflater.from(mContext);
}
@Override
public int getCount() {
return indexTitles.size();
}
@Override
public Object getItem(int position) {
return indexTitles.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.dua_row, null);
holder.mainBg = (RelativeLayout) convertView.findViewById(R.id.duaBG);
holder.title_text = (TextView) convertView.findViewById(R.id.title_text);
holder.buttonPlayPause = (ImageButton) convertView.findViewById(R.id.imageButton);
holder.buttonPlayPause.setFocusable(false);
holder.buttonPlayPause.setFocusableInTouchMode(false);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
String leftRemoved = indexTitles.get(position).trim();
holder.title_text.setText(leftRemoved);
// /player selection
if (playPos == position) {
holder.buttonPlayPause.setBackgroundResource(R.drawable.buttonpause);
holder.mainBg.setBackgroundColor(Color.parseColor("#000000"));
holder.title_text.setTextColor(Color.parseColor("#D59D52"));
} else {
holder.buttonPlayPause.setVisibility(View.GONE);
holder.title_text.setTextColor(Color.parseColor("#000000"));
holder.mainBg.setBackgroundColor(Color.parseColor("#D59D52"));
}
return convertView;
}
List Row
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
android:id="@+id/duaBG"
android:background="#D59D52">
<TextView
android:layout_width="match_parent"
android:layout_height="32dp"
android:text=""
android:textSize="18dp"
android:id="@+id/title_text"
android:ellipsize="end"
android:maxLines="1"
android:layout_alignParentTop="true"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginTop="@dimen/activity_horizontal_margin"
android:layout_marginBottom="@dimen/activity_horizontal_margin"
android:layout_toLeftOf="@+id/imageButton"
android:layout_toStartOf="@+id/imageButton" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageButton"
android:focusable="false"
android:visibility="gone"
android:background="@drawable/buttonpause"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="5dp"
android:background="#000000"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"></LinearLayout>
OnItemClickListener
// indexTitles is ArrayList<String>
indexTitles = getIndexTitles();
final ListAdapter adapter = new ListAdapter(this);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final View v = view.findViewById(R.id.imageButton);
v.setVisibility(View.VISIBLE);
if (mediaPlayer.isPlaying() && playPos == position) {
// pause mediaplayer
mediaPlayer.pause();
MEDIA_PAUSED = true;
v.setBackgroundResource(R.drawable.buttonplay);
} else if (MEDIA_PAUSED && !mediaPlayer.isPlaying() && playPos == position) {
MEDIA_PAUSED = false;
mediaPlayer.start();
v.setBackgroundResource(R.drawable.buttonpause);
} else if (!mediaPlayer.isPlaying() || mediaPlayer.isPlaying() && playPos != position) {
// release and start from this position
mediaPlayer.reset();
v.setVisibility(View.VISIBLE);
v.setBackgroundResource(R.drawable.buttonpause);
String s = String.format("%03d", position + 2);
String Path = SDCARD_PATH + "/DoaData/DD_" + s + ".mp3";
playPos = position;
adapter.notifyDataSetChanged();
File file = new File(Path);
Uri uri = Uri.fromFile(file);
try {
mediaPlayer.setDataSource(context, uri);
mediaPlayer.prepare();
mediaPlayer.start();
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
v.setBackgroundResource(R.drawable.buttonplay);
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
What Needed I want to imageButton to keep its state about being played or paused.
Thanks
Simply set the visibility inside the IF statement like this:
if (playPos == position) {
holder.buttonPlayPause.setVisibility(View.VISIBLE);
// further implementation
} else {
holder.buttonPlayPause.setVisibility(View.GONE);
// further implementation
}
The problem occured, because the list adapter recycles the old views. When one view is not visible and the list is creating the new view using an old one, you have to set every different property again, else all properties from the previous view object are recycled/reused.