Reputation: 2049
I am developing a music player app. In this I ll retrieving all the music files available in the sdcard and display in a list.
There will be a play button inside the list inorder to play the song.
Initially, all the images will be of "PLAY BUTTON" state.
then when the user clicks the play button, the play button will change to this.
and the music will play/pause accordingly.
But, the problem I am facing is, if I play the first song, the song gets played and the icon changes, but if I scroll down the list, the "PAUSE" button image appears randomly for any song on the list.
Below is the code: (Its still under developemnt when it comes to playing music, but I ned to solve this image issue)
MusicActivity:
package sample.music;
import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class MusicActivity extends Activity {
ListView musiclist;
Cursor musiccursor;
int music_column_index;
int count;
MediaPlayer mMediaPlayer;
private static LayoutInflater inflater = null;
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
mMediaPlayer.release();
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
init_phone_music_grid();
}
private void init_phone_music_grid() {
System.gc();
String[] proj = { MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.DISPLAY_NAME,
MediaStore.Video.Media.SIZE };
musiccursor = managedQuery(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
proj, null, null, null);
count = musiccursor.getCount();
musiclist = (ListView) findViewById(R.id.PhoneMusicList);
musiclist.setAdapter(new MusicAdapter(getApplicationContext()));
musiclist.setDividerHeight(50);
// musiclist.setOnItemClickListener(musicgridlistener);
mMediaPlayer = new MediaPlayer();
}
static class ViewHolder {
TextView textView;
ImageView imageView;
}
public class MusicAdapter extends BaseAdapter {
private Context mContext;
public MusicAdapter(Context c) {
mContext = c;
}
public int getCount() {
return count;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
System.gc();
String id = null;
View vi = convertView;
final int muscPosition = position;
final ViewHolder viewHolder;
if (convertView == null) {
inflater = MusicActivity.this.getLayoutInflater();
vi = inflater.inflate(R.layout.item, null);
}
viewHolder = new ViewHolder();
viewHolder.textView = (TextView) vi.findViewById(R.id.text);
viewHolder.imageView = (ImageView) vi.findViewById(R.id.image);
//final ImageView tempView = viewHolder.imageView;
viewHolder.imageView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
music_column_index = musiccursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
musiccursor.moveToPosition(muscPosition);
String filename = musiccursor
.getString(music_column_index);
try {
if (mMediaPlayer.isPlaying()) {
Toast.makeText(MusicActivity.this,
"mMediaPlayer.isPlaying()",
Toast.LENGTH_LONG).show();
try {
mMediaPlayer.stop();
mMediaPlayer.release();
viewHolder.imageView.setImageResource(R.drawable.play_button);
//notifyDataSetChanged();
} catch (Exception e) {
// TODO: handle exception
Toast.makeText(MusicActivity.this, e + "",
Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(MusicActivity.this,
"mMediaPlayer.start", Toast.LENGTH_LONG)
.show();
viewHolder.imageView.setImageResource(R.drawable.pause_button);
//notifyDataSetChanged();
mMediaPlayer.setDataSource(filename);
mMediaPlayer.prepare();
mMediaPlayer.start();
}
} catch (Exception e) {
Toast.makeText(MusicActivity.this, e + ""+".....",
Toast.LENGTH_LONG).show();
}
}
});
music_column_index = musiccursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME);
musiccursor.moveToPosition(position);
id = musiccursor.getString(music_column_index);
music_column_index = musiccursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE);
musiccursor.moveToPosition(position);
id += " Size(KB):" + musiccursor.getString(music_column_index);
vi.setTag(viewHolder);
viewHolder.textView.setText(id);
return vi;
}
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView
android:id="@+id/PhoneMusicList"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/image"
android:layout_width="50dip"
android:layout_height="50dip" android:src="@drawable/play_button" android:scaleType="centerCrop"/>
<TextView
android:id="@+id/text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1" android:layout_gravity="left|center_vertical" android:textSize="20dip" android:layout_marginLeft="10dip"/>
</LinearLayout>
Upvotes: 1
Views: 3502
Reputation: 14058
The problem you are facing is the recycled view you are getting contains the pause image. You just need to explicitly check it.Try the below code :
int pause_button_position=-1; //add
public View getView(int position, View convertView, ViewGroup parent) {
System.gc();
String id = null;
View vi = convertView;
final int muscPosition = position;
final ViewHolder viewHolder;
if (convertView == null) {
inflater = MusicActivity.this.getLayoutInflater();
vi = inflater.inflate(R.layout.item, null);
}
viewHolder = new ViewHolder();
viewHolder.textView = (TextView) vi.findViewById(R.id.text);
viewHolder.imageView = (ImageView) vi.findViewById(R.id.image);
if(position!=pause_button_position)
viewHolder.imageView.setImageResource(R.drawable.play_button); //add this line
//final ImageView tempView = viewHolder.imageView;
viewHolder.imageView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
music_column_index = musiccursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
musiccursor.moveToPosition(muscPosition);
String filename = musiccursor
.getString(music_column_index);
try {
if (mMediaPlayer.isPlaying()) {
Toast.makeText(MusicActivity.this,
"mMediaPlayer.isPlaying()",
Toast.LENGTH_LONG).show();
try {
mMediaPlayer.stop();
mMediaPlayer.release();
viewHolder.imageView.setImageResource(R.drawable.play_button);
//notifyDataSetChanged();
} catch (Exception e) {
// TODO: handle exception
Toast.makeText(MusicActivity.this, e + "",
Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(MusicActivity.this,
"mMediaPlayer.start", Toast.LENGTH_LONG)
.show();
viewHolder.imageView.setImageResource(R.drawable.pause_button);
pause_button_position=position; //add
//notifyDataSetChanged();
mMediaPlayer.setDataSource(filename);
mMediaPlayer.prepare();
mMediaPlayer.start();
}
} catch (Exception e) {
Toast.makeText(MusicActivity.this, e + ""+".....",
Toast.LENGTH_LONG).show();
}
}
});
music_column_index = musiccursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME);
musiccursor.moveToPosition(position);
id = musiccursor.getString(music_column_index);
music_column_index = musiccursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE);
musiccursor.moveToPosition(position);
id += " Size(KB):" + musiccursor.getString(music_column_index);
vi.setTag(viewHolder);
viewHolder.textView.setText(id);
return vi;
}
Upvotes: 0
Reputation: 2679
This is a common problem, what we need to realize is that unlike scroll view where everything is drawn at once, In ListView things are drawn on run-time. So I suggest maintaining a collection which stores the state of the button for each list item in the adapter.
In the get view function change the drawble on the button.
When some button is clicked change the state of the button in the collection in the adapter.
I hope this answers you question.
Upvotes: 3