我在我的新应用程序中使用此项目,该应用程序显示带有播放按钮和SeekBar进度的曲目列表。我能够播放曲目但是我在更新SeekBar时遇到了问题。
我使用Runnable和Handler来更新SeekBar。 当我点击游戏时,该子视图的SeekBar正确移动,但处于可回收位置的孩子也得到了更新。例如,我有一个包含10个项目的列表,仅包含5个可见项目。当第一首曲目的SeekBar得到更新时,第6首曲目也进行了更新。如果我有更大的名单,同样的事情发生在第11或第16位...... 有关如何正确更新它的任何建议吗?
这是适配器
public class ListViewAdapter extends BaseAdapter {
private Activity activity;
private List<Ring> list;
private LayoutInflater inflater;
private int mediaFileLengthInMilliseconds;
private final Handler handler = new Handler();
private MediaPlayer player;
private AssetManager assetManager;
public ListViewAdapter(Activity activity, List<Ring> list) {
this.activity = activity;
this.list = list;
this.inflater = LayoutInflater.from(this.activity);
assetManager = activity.getAssets();
player = new MediaPlayer();
}
@Override
public int getCount() {
return list.size();
}
@Override
public Ring getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = this.inflater.inflate(R.layout.list_view_item, parent, false);
holder.play = (ImageButton) convertView.findViewById(R.id.play);
holder.fav = (Button) convertView.findViewById(R.id.fav);
holder.set = (Button) convertView.findViewById(R.id.setAs);
holder.title = (TextView) convertView.findViewById(R.id.title);
holder.seekBarProgress = (SeekBar) convertView.findViewById(R.id.bar);
holder.seekBarProgress.setMax(99);
holder.seekBarProgress.setEnabled(false);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
holder.title.setText(list.get(position).getName());
holder.title.setTypeface(Typeface.createFromAsset(activity.getAssets(), "fonts/OpenSans-Light.ttf"));
holder.play.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (player.isPlaying()) {
player.pause();
holder.play.setImageDrawable(ResourcesCompat.getDrawable(activity.getResources(), android.R.drawable.ic_media_play, null));
holder.primarySeekBarProgressUpdater();
} else {
player.reset();
AssetFileDescriptor afd = null;
try {
afd = assetManager.openFd(list.get(position).getName() + ".mp3");
player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
player.prepare();
player.start();
mediaFileLengthInMilliseconds = player.getDuration();
player.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
holder.seekBarProgress.setSecondaryProgress(percent);
}
});
holder.seekBarProgress.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (v.getId() == R.id.bar) {
if (player.isPlaying()) {
SeekBar sb = (SeekBar) v;
int playPositionInMillisecconds = (mediaFileLengthInMilliseconds / 100) * sb.getProgress();
player.seekTo(playPositionInMillisecconds);
}
}
return true;
}
});
player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
holder.play.setImageDrawable(ResourcesCompat.getDrawable(activity.getResources(), android.R.drawable.ic_media_play, null));
}
});
holder.primarySeekBarProgressUpdater();
holder.play.setImageDrawable(ResourcesCompat.getDrawable(activity.getResources(), android.R.drawable.ic_media_pause, null));
}catch (IOException e) {
e.printStackTrace();
}
}
}
});
return convertView;
}
private class ViewHolder {
TextView title;
ImageButton play;
Button set;
Button fav;
SeekBar seekBarProgress;
void primarySeekBarProgressUpdater() {
seekBarProgress.setProgress((int) (((float) player.getCurrentPosition() / mediaFileLengthInMilliseconds) * 100)); // This math construction give a percentage of "was playing"/"song length"
if (player.isPlaying()) {
Runnable notification = new Runnable() {
public void run() {
primarySeekBarProgressUpdater();
}
};
handler.postDelayed(notification,100);
}
}
}
}
答案 0 :(得分:2)
正如您已经指出的那样,列表视图项目被回收。因此,您的Handler
应该使用SeekBar
的值更新支持数据模型,并在适配器上调用notifyDataSetChanged()
。 SeekBar
值的实际设置应由适配器的getView()
处理。
这不是一个完美的解决方法,因为您的代码存在很多问题,但它应该解决您正在更新的多个列表项的问题。
position
变量添加到支持列表模型。primarySeekBarProgressUpdater
notifyDataSetChanged()
getView
中,根据您的支持数据模型设置搜索栏位置 void primarySeekBarProgressUpdater(final int i) {
list.get(i).setPosition((int) (((float) player.getCurrentPosition() / mediaFileLengthInMilliseconds) * 100)); // This math construction give a percentage of "was playing"/"song length"
notifyDataSetChanged();
if (player.isPlaying()) {
Runnable notification = new Runnable() {
public void run() {
primarySeekBarProgressUpdater(i);
}
};
handler.postDelayed(notification,100);
}
}
public View getView(final int position, View convertView, ViewGroup parent) {
...
holder.seekBarProgress.setProgress(list.get(position).getPosition());
...
}