SeekBar 未更新 Android
SeekBar not updating Android
我的 ListView
项目中有一个 SeekBar
。并为每个项目一首歌。播放歌曲时,我希望 SeekBar
更新和/或控制 MediaPlayer
与 SeekBar
的进度。
到目前为止,我只是通过拖动拇指来控制它来设置 MediaPlayer
进度。问题是,我无法让它更新 SeekBar Thumb 位置。
这是我的代码:
Ids holder;
private final Utils utils = new Utils();
private final Handler handler = new Handler();
long totalDuration;
long currentPosition;
...
holder.seekbar.setMax(100);
holder.seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
handler.removeCallbacks(updateTimeProgressBar);
int fullDuration = Item.mp.getDuration();
int currentPosition = utils.progressToTimer(
seekBar.getProgress(), fullDuration);
Item.mp.seekTo(currentPosition);
updateProgressBar();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
handler.removeCallbacks(updateTimeProgressBar);
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
}
});
holder.seekbar.setFocusable(true);
holder.seekbar.setEnabled(true);
holder.seekbar.setTag(position);
...
播放文件
Item.mp = MediaPlayer.create(context,
Integer.valueOf(this.songPos[songPosInt]).intValue());
Item.mp.start();
holder.seekbar.setProgress(0);
updateProgressBar();
最后更新 SeekBar 的代码
public void updateProgressBar() {
handler.postDelayed(updateTimeProgressBar, 1000);
}
private final Runnable updateTimeProgressBar = new Runnable() {
@Override
public void run() {
if (Item.isPlaying == true && pausedSamePos == false) {
currentPosition = Item.mp.getCurrentPosition();
totalDuration = mp.getDuration();
int currentTime = (utils.getProgressPercentage(totalDuration,
currentPosition));
holder.seekbar.setProgress(currentTime);
Log.i("CALLED", "SHOULD BE UPDATED " + currentPosition
+ "of total" + totalDuration);
handler.postDelayed(this, 1000);
}
}
};
Utils 是一个简单的助手 class 将 MS 转换为 SEC
我也试过
int totalDuration=mp.getDuration() /1000;
holder.seekbar.setMax(totalduration);
..
int currentPosition=mp.getCurrentPosition()/1000;
holder.seekbar.setProgress(currentPosition);
搜索栏
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_frame3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal" >
<SeekBar
android:id="@+id/seekbar"
android:layout_width="0.0dip"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:paddingLeft="5.0dip"
android:paddingRight="5.0dip"
android:progressDrawable="@drawable/seekbar_line"
android:thumb="@drawable/seekbar_thumb" />
<TextView
android:id="@+id/textview_duration_sb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="10.0dip"
android:text="00:05"
android:textAppearance="?android:textAppearanceSmall"
android:textColor="#8C000000" />
</LinearLayout>
并且在我的 ListView 视图中
<FrameLayout
android:id="@+id/main_frame2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5.0dip" >
<TextView
android:id="@+id/textview_duration"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:focusable="false"
android:text="00:05"
android:textColor="#8C000000"
android:textSize="14.0sp" />
<include layout="@layout/play_item" />
</FrameLayout>
这是我的实现,它对我有用:
在您的代码中的某处添加(每首歌曲一次):
_seekBar.setProgress(0);
_seekBar.setMax(_mediaPlayer.getDuration() / 1000);
然后使用此代码更新搜索栏:
private Runnable _updateRunnable = new Runnable() {
public void run() {
if (_hasStopped) {
return;
}
updateSeekbarView();
}
};
private synchronized void updateSeekbarView() {
if (_hasStopped) {
reset();
return;
}
if (_mediaPlayer == null) {
return;
}
if (!_mediaPlayer.isPlaying()) {
stop();
return;
}
long totalDuration = _mediaPlayer.getDuration();
long currentDuration = _mediaPlayer.getCurrentPosition();
_txtMax.setText("" + AudioUtils.milliSecondsToTimer(totalDuration));
_txtCurrent.setText("" + AudioUtils.milliSecondsToTimer(currentDuration));
_seekBar.setProgress((int) (currentDuration / 1000));
_handler.postDelayed(_updateRunnable, 1000);
}
和 AudioUtils.milliSecondsToTimer()
实现,以防您想将计时器显示为搜索栏旁边的文本:
public static String milliSecondsToTimer(long milliseconds) {
String finalTimerString = "";
String secondsString = "";
// Convert total duration into time
int hours = (int) (milliseconds / (1000 * 60 * 60));
int minutes = (int) (milliseconds % (1000 * 60 * 60)) / (1000 * 60);
int seconds = (int) ((milliseconds % (1000 * 60 * 60)) % (1000 * 60) / 1000);
// Add hours if there
if (hours > 0) {
finalTimerString = hours + ":";
}
// Prepending 0 to seconds if it is one digit
if (seconds < 10) {
secondsString = "0" + seconds;
} else {
secondsString = "" + seconds;
}
finalTimerString = finalTimerString + minutes + ":" + secondsString;
// return timer string
return finalTimerString;
}
在这种情况下,我认为 holder 引用被转储或更改为另一个视图。
您可以通过在 getView 方法中初始化 Runnable 来解决这个问题,如下所示:
View getView(){
...
updateTimeProgressBar = new Runnable() {
Ids holderCopy = holder;
@Override
public void run() {
if (Item.isPlaying == true && pausedSamePos == false) {
currentPosition = Item.mp.getCurrentPosition();
totalDuration = mp.getDuration();
int currentTime = (utils.getProgressPercentage(totalDuration,
currentPosition));
holderCopy.seekbar.setProgress(currentTime);
Log.i("CALLED", "SHOULD BE UPDATED " + currentPosition
+ "of total" + totalDuration);
handler.postDelayed(this, 1000);
}
}
};
}
但我真的需要知道你是如何演奏你的歌曲才能进一步帮助你...
问题是,错误的 SeekBar
正在更新。因此,只需在 clickListener
中添加 SeekBar
侦听器和 runnable
即可。同时扩展基本适配器并获取项目 ID。
我的 ListView
项目中有一个 SeekBar
。并为每个项目一首歌。播放歌曲时,我希望 SeekBar
更新和/或控制 MediaPlayer
与 SeekBar
的进度。
到目前为止,我只是通过拖动拇指来控制它来设置 MediaPlayer
进度。问题是,我无法让它更新 SeekBar Thumb 位置。
这是我的代码:
Ids holder;
private final Utils utils = new Utils();
private final Handler handler = new Handler();
long totalDuration;
long currentPosition;
...
holder.seekbar.setMax(100);
holder.seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
handler.removeCallbacks(updateTimeProgressBar);
int fullDuration = Item.mp.getDuration();
int currentPosition = utils.progressToTimer(
seekBar.getProgress(), fullDuration);
Item.mp.seekTo(currentPosition);
updateProgressBar();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
handler.removeCallbacks(updateTimeProgressBar);
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
}
});
holder.seekbar.setFocusable(true);
holder.seekbar.setEnabled(true);
holder.seekbar.setTag(position);
... 播放文件
Item.mp = MediaPlayer.create(context,
Integer.valueOf(this.songPos[songPosInt]).intValue());
Item.mp.start();
holder.seekbar.setProgress(0);
updateProgressBar();
最后更新 SeekBar 的代码
public void updateProgressBar() {
handler.postDelayed(updateTimeProgressBar, 1000);
}
private final Runnable updateTimeProgressBar = new Runnable() {
@Override
public void run() {
if (Item.isPlaying == true && pausedSamePos == false) {
currentPosition = Item.mp.getCurrentPosition();
totalDuration = mp.getDuration();
int currentTime = (utils.getProgressPercentage(totalDuration,
currentPosition));
holder.seekbar.setProgress(currentTime);
Log.i("CALLED", "SHOULD BE UPDATED " + currentPosition
+ "of total" + totalDuration);
handler.postDelayed(this, 1000);
}
}
};
Utils 是一个简单的助手 class 将 MS 转换为 SEC 我也试过
int totalDuration=mp.getDuration() /1000;
holder.seekbar.setMax(totalduration);
..
int currentPosition=mp.getCurrentPosition()/1000;
holder.seekbar.setProgress(currentPosition);
搜索栏
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_frame3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal" >
<SeekBar
android:id="@+id/seekbar"
android:layout_width="0.0dip"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:paddingLeft="5.0dip"
android:paddingRight="5.0dip"
android:progressDrawable="@drawable/seekbar_line"
android:thumb="@drawable/seekbar_thumb" />
<TextView
android:id="@+id/textview_duration_sb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="10.0dip"
android:text="00:05"
android:textAppearance="?android:textAppearanceSmall"
android:textColor="#8C000000" />
</LinearLayout>
并且在我的 ListView 视图中
<FrameLayout
android:id="@+id/main_frame2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5.0dip" >
<TextView
android:id="@+id/textview_duration"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:focusable="false"
android:text="00:05"
android:textColor="#8C000000"
android:textSize="14.0sp" />
<include layout="@layout/play_item" />
</FrameLayout>
这是我的实现,它对我有用:
在您的代码中的某处添加(每首歌曲一次):
_seekBar.setProgress(0);
_seekBar.setMax(_mediaPlayer.getDuration() / 1000);
然后使用此代码更新搜索栏:
private Runnable _updateRunnable = new Runnable() {
public void run() {
if (_hasStopped) {
return;
}
updateSeekbarView();
}
};
private synchronized void updateSeekbarView() {
if (_hasStopped) {
reset();
return;
}
if (_mediaPlayer == null) {
return;
}
if (!_mediaPlayer.isPlaying()) {
stop();
return;
}
long totalDuration = _mediaPlayer.getDuration();
long currentDuration = _mediaPlayer.getCurrentPosition();
_txtMax.setText("" + AudioUtils.milliSecondsToTimer(totalDuration));
_txtCurrent.setText("" + AudioUtils.milliSecondsToTimer(currentDuration));
_seekBar.setProgress((int) (currentDuration / 1000));
_handler.postDelayed(_updateRunnable, 1000);
}
和 AudioUtils.milliSecondsToTimer()
实现,以防您想将计时器显示为搜索栏旁边的文本:
public static String milliSecondsToTimer(long milliseconds) {
String finalTimerString = "";
String secondsString = "";
// Convert total duration into time
int hours = (int) (milliseconds / (1000 * 60 * 60));
int minutes = (int) (milliseconds % (1000 * 60 * 60)) / (1000 * 60);
int seconds = (int) ((milliseconds % (1000 * 60 * 60)) % (1000 * 60) / 1000);
// Add hours if there
if (hours > 0) {
finalTimerString = hours + ":";
}
// Prepending 0 to seconds if it is one digit
if (seconds < 10) {
secondsString = "0" + seconds;
} else {
secondsString = "" + seconds;
}
finalTimerString = finalTimerString + minutes + ":" + secondsString;
// return timer string
return finalTimerString;
}
在这种情况下,我认为 holder 引用被转储或更改为另一个视图。
您可以通过在 getView 方法中初始化 Runnable 来解决这个问题,如下所示:
View getView(){
...
updateTimeProgressBar = new Runnable() {
Ids holderCopy = holder;
@Override
public void run() {
if (Item.isPlaying == true && pausedSamePos == false) {
currentPosition = Item.mp.getCurrentPosition();
totalDuration = mp.getDuration();
int currentTime = (utils.getProgressPercentage(totalDuration,
currentPosition));
holderCopy.seekbar.setProgress(currentTime);
Log.i("CALLED", "SHOULD BE UPDATED " + currentPosition
+ "of total" + totalDuration);
handler.postDelayed(this, 1000);
}
}
};
}
但我真的需要知道你是如何演奏你的歌曲才能进一步帮助你...
问题是,错误的 SeekBar
正在更新。因此,只需在 clickListener
中添加 SeekBar
侦听器和 runnable
即可。同时扩展基本适配器并获取项目 ID。