gpt4 book ai didi

android - ListView 中的音频播放器与 Android 中的搜索栏

转载 作者:搜寻专家 更新时间:2023-11-01 08:00:16 24 4
gpt4 key购买 nike

一切正常,但搜索栏在每个 ListView 中更新,但音频正在播放正确的方法

public class AudioPLayAdapter extends BaseAdapter implements
OnCompletionListener, SeekBar.OnSeekBarChangeListener {
private Activity activity;

private ArrayList<String> al_fname = new ArrayList<String>();
private static LayoutInflater inflater = null;
private boolean flag_play;
private MediaPlayer mPlayer = null;

Handler seekHandler = new Handler();

public AudioPLayAdapter(Activity a, ArrayList<String> al_fname) {
activity = a;
mPlayer = new MediaPlayer();
this.al_fname = al_fname;
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

}

@Override
public View getView(final int position, final View convertView,
final ViewGroup parent) {
View vi = convertView;

if (convertView == null)
vi = inflater.inflate(R.layout.audi_rec_lv_layout, null);

final Button play_btn = (Button) vi.findViewById(R.id.play_stop_button);

final SeekBar seekBar = (SeekBar) vi.findViewById(R.id.seekbar_play);

play_btn.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (!flag_play) {
play_btn.setText("Stop");
startPlaying();

flag_play = true;
} else {
play_btn.setText("Play");
mPlayer.stop();
seekBar.setProgress(0);
flag_play = false;
}

}

private void startPlaying() {
// TODO Auto-generated method stub

try {

mPlayer.reset();
FileInputStream rawFile = new FileInputStream(al_fname
.get(position));
Log.e("filename", al_fname.get(position));
mPlayer.setDataSource(rawFile.getFD());
// mPlayer.setDataSource(mFileName);
mPlayer.prepare();
mPlayer.start();
// set Progress bar values

seekBar.setProgress(0);
seekBar.setMax(100);

// seekHandler.postDelayed(updateSeek, 100);
// Updating progress bar

updateProgressBar();

} catch (IOException e) {
Log.e("preparefailed", "prepare() failed");
}

}

private void updateProgressBar() {
// TODO Auto-generated method stub

seekHandler.postDelayed(mUpdateTimeTask, 100);
}

private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
long totalDuration = mPlayer.getDuration();
long currentDuration = mPlayer.getCurrentPosition();
String str1 = new String();
// holder.timer_tv.setText(str1.valueOf(currentDuration));
// Updating progress bar
int progress = (int) (getProgressPercentage(
currentDuration, totalDuration));
// Log.d("Progress", ""+progress);
// if(position==holder.seekBar.getId())
// seekBar.setTag(position);
seekBar.setProgress(progress);

// Running this thread after 100 milliseconds
seekHandler.postDelayed(this, 100);
if (!mPlayer.isPlaying()) {
play_btn.setText("Play");

flag_play = false;
}
if (!flag_play)
seekBar.setProgress(0);

}

private int getProgressPercentage(long currentDuration,
long totalDuration) {
// TODO Auto-generated method stub
Double percentage = (double) 0;

long currentSeconds = (int) (currentDuration / 1000);
long totalSeconds = (int) (totalDuration / 1000);

// calculating percentage
percentage = (((double) currentSeconds) / totalSeconds) * 100;

// return percentage
return percentage.intValue();
}
};

});
return vi;
}

@Override
public int getCount() {
// TODO Auto-generated method stub
return al_fname.size();
}

@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}

@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}

@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub

}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub

}

@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub

}

@Override
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub

}

}

最佳答案

每次调用 getView 时,都会创建一个新的 OnClickListener 并将其添加到该行 View 的 play_btn 中。

这些匿名 OnClickListener 中的每一个都有一个字段 Runnable mUpdateTimeTask。这个 runnable 被发布到处理程序,然后它不断地一次又一次地发布自己。

当新行开始播放时,现在有两个 Runnable 发布它们自己并更新可能不同的搜索栏。每次点击播放时,都会添加一个新的额外可运行对象。

您想要的是跟踪正在播放的项目,并在不再需要时停止发布可运行的项目。一次最多应该有 1 个可运行的。甚至可能寻找一种更好的方法来定期更新搜索栏(如果存在)。

getView 中,如果 View 被回收(即它来自 convertView 参数),那么您必须检查 View 现在是否用于不同的 位置,如果是不同的位置,则停止更新该行的seekbar

所以你需要这样的东西(仍然缺少一些细节,例如处理歌曲何时结束,或如何停止播放,留作练习):(完整的演示项目位于 https://github.com/curobosqui/PlaybackInList/tree/StackoverfllowAnswer)

public class ListWithSongsActivity extends ListActivity {
private static final int NOT_PLAYING = -1;

private static final String TAG = "SongList";

List<String> mSongs = new ArrayList<String>(50);
private ArrayAdapter<String> mAdapter = null;
private final MediaPlayer mPlayer = new MediaPlayer();
private int mPlayingPosition = NOT_PLAYING;
private Handler mHandler = new Handler();

private PlaybackUpdater mProgressUpdater = new PlaybackUpdater();

public ListWithSongsActivity() {
//add list of songs in your device for sample
mSongs.addAll(Arrays.asList(new String[]{
"/sdcard/Download/B00G2ID7FE_(disc_1)_01_-_Play_Me_(Version).mp3",
"/sdcard/Download/The Slip/10 Demon Seed.mp3"
}));
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_list_with_songs);
mAdapter = new ArrayAdapter<String>(this, R.layout.list_item, android.R.id.text1, mSongs) {

@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);
ProgressBar pb = (ProgressBar) v.findViewById(R.id.progressBar1); //Cast
if (position == mPlayingPosition) {
//pb.setVisibility(View.VISIBLE);
mProgressUpdater.mBarToUpdate = pb;
mHandler.postDelayed(mProgressUpdater, 100);
} else {
//pb.setVisibility(View.GONE);
pb.setProgress(0);
if (mProgressUpdater.mBarToUpdate == pb) {
//this progress would be updated, but this is the wrong position
mProgressUpdater.mBarToUpdate = null;
}
}
return v;
}
};
setListAdapter(mAdapter);
}

private void stopPlayback()
{
mPlayingPosition = NOT_PLAYING;
mProgressUpdater.mBarToUpdate = null;
mPlayer.stop();
}

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);

//start playing item at position
try {
mPlayer.reset();
mPlayer.setDataSource(mSongs.get(position));
mPlayer.prepare();
mPlayer.start();
mPlayingPosition = position;

mHandler.postDelayed(mProgressUpdater, 500);

//trigger list refresh, this will make progressbar start updating if visible
mAdapter.notifyDataSetChanged();
} catch (IOException e) {
Log.e(TAG, "unable to play: " + mSongs.get(position));
e.printStackTrace();
stopPlayback();
}
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.list_with_songs, menu);
return true;
}

@Override
protected void onStop() {
super.onStop();
mPlayer.stop();
}

private class PlaybackUpdater implements Runnable {
public ProgressBar mBarToUpdate = null;

@Override
public void run() {
if ((mPlayingPosition != NOT_PLAYING) && (null != mBarToUpdate)) {
mBarToUpdate.setProgress( (100*mPlayer.getCurrentPosition() / mPlayer.getDuration()) ); //Cast
mHandler.postDelayed(this, 500);
} else {
//not playing so stop updating
}
}
}
}

并使用简单的行布局 list_item.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView" />

<ProgressBar
android:id="@+id/progressBar1"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

</LinearLayout>

关于android - ListView 中的音频播放器与 Android 中的搜索栏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22216500/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com