首先来看一下效果图,如下所示:
其中进度条如下:
接下来说一说我的思路,上面的进度拖动条有自定义的Thumb,在Thumb正上方有一个PopupWindow窗口,窗口里面显示当前的播放时间。在SeekBar右边有一个文本框显示当前播放时间/总时间。
step1、先来看一看PopupWindow的布局文件,seek_popu.xml,效果如下图所示:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/seek_dialog_bg" >
<!-- 展现当前播放进度时间的文本框-->
<TextView
android:id="@+id/dialogSeekTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dip"
android:layout_marginTop="12dip"
android:text="@string/unknow_seek_time"
android:textColor="@color/black"
android:textSize="12sp" />
</RelativeLayout>
step2、自定义一个SeekBar
import com.canplay.video.R;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.PopupWindow;
import android.widget.SeekBar;
import android.widget.TextView;
public class MySeekBar extends SeekBar {
private PopupWindow mPopupWindow;
private View mView;
private TextView dialogSeekTime;
private int[] mPosition;
private final int mThumbWidth = 25;
public MySeekBar(Context context) {
this(context, null);
}
public MySeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
mView = LayoutInflater.from(context).inflate(R.layout.seek_popu, null);
dialogSeekTime = (TextView) mView.findViewById(R.id.dialogSeekTime);
mPopupWindow = new PopupWindow(mView, mView.getWidth(), mView.getHeight(), true);
mPosition = new int[2];
}
private int getViewWidth(View v) {
int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
v.measure(w, h);
return v.getMeasuredWidth();
}
private int getViewHeight(View v) {
int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
v.measure(w, h);
return v.getMeasuredHeight();
}
public void hideSeekDialog() {
if (mPopupWindow != null && mPopupWindow.isShowing()) {
mPopupWindow.dismiss();
}
}
public void showSeekDialog(String str) {
dialogSeekTime.setText(str);
int progress = this.getProgress();
// 计算每个进度值所占的宽度
int thumb_x = (int) (progress * (1.0f * (this.getWidth() - 22) / this.getMax())); //22是两边的空白部分宽度
// 更新后的PopupWindow的Y坐标
int middle = this.getHeight() / 2 + 120;
if (mPopupWindow != null) {
try {
this.getLocationOnScreen(mPosition);
// 相对某个控件的位置(正左下方),在X、Y方向各有偏移
mPopupWindow.showAsDropDown(this, (int) mPosition[0], mPosition[1]);
int x = thumb_x + mPosition[0] - getViewWidth(mView) / 2 + mThumbWidth / 2;
// 更新popup窗口的位置
mPopupWindow.update(x, middle, getViewWidth(mView), getViewHeight(mView));
} catch (Exception e) {
}
}
}
}
step3、将自定义的拖动条加入到布局文件中,下面是部分代码
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@android:color/black" >
......
<!-- 进度拖动条 -->
<RelativeLayout
android:id="@+id/seek_bar_container"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="@id/control_btn_container"
android:background="@drawable/seek_bg" >
<com.canplay.video.view.MySeekBar
android:id="@+id/seek_progress"
android:layout_width="600dip"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
<TextView
android:id="@+id/currentTime"
style="@style/seekTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="@id/seek_progress"
android:paddingLeft="20dip"
android:text="@string/unknow_time" />
</RelativeLayout>
...............
</RelativeLayout>
step4、在主文件中对拖动条进行托动监听
mSeekBar = (MySeekBar) findViewById(R.id.seek_progress);
mSeekBar.setOnSeekBarChangeListener(mSeekBarListener);
private OnSeekBarChangeListener mSeekBarListener = new OnSeekBarChangeListener() {
// 通知进度已经被修改
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (isTouchSeeked) {
mSeekBar.showSeekDialog(makeTimeString(progress));//动态展示当前播放时间
} else {
mSeekBar.hideSeekDialog();
}
}
// 通知用户已经开始一个触摸拖动手势
public void onStartTrackingTouch(SeekBar seekBar) {
showControlView(3600000);
isTouchSeeked = true;
}
// 通知用户触摸手势已经结束
public void onStopTrackingTouch(SeekBar seekBar) {
Message msg = Message.obtain();
msg.what = PROGRESS_SEEKTO;
msg.arg1 = seekBar.getProgress();
mHandler.removeMessages(PROGRESS_SEEKTO);
mHandler.sendMessageAtTime(msg, 1000);// 1秒之后开始发送更新进度的消息
isTouchSeeked = false;
showControlView(sDefaultTimeout);
}
};
其中将进度值转换为时间的方法makeTimeString(int secs)如下所示:
private StringBuilder sFormatBuilder = new StringBuilder();
private Formatter sFormatter = new Formatter(sFormatBuilder, Locale.getDefault());
private final Object[] sTimeArgs = new Object[3];
private String makeTimeString(int secs) {
String durationformat = getString(R.string.durationformat);// <xliff:g
// id="format">%1$02d:%2$02d:%3$02d</xliff:g>
sFormatBuilder.setLength(0);
secs = secs / 1000;
Object[] timeArgs = sTimeArgs;
timeArgs[0] = secs / 3600; // 秒
timeArgs[1] = (secs % 3600) / 60; // 分
timeArgs[2] = (secs % 3600 % 60) % 60; // 时
return sFormatter.format(durationformat, timeArgs).toString().trim();
}
当然,这里只是简单的介绍了下自定义进度条,而该进度条的样式都没有展现出来,样式读者可以自己定义。
您可能感兴趣的文章:Android 可拖动的seekbar自定义进度值Android利用SeekBar实现简单音乐播放器Android 中Seekbar详解及简单实例Android控件之SeekBar的用法总结Android控件SeekBar仿淘宝滑动验证效果Android 动态改变SeekBar进度条颜色与滑块颜色的实例代码Android自定义竖直方向SeekBar多色进度条android之SeekBar控件用法详解Android自定义SeekBar滑动显示数字Android关于SeekBar无法点击到最大值问题解决方法记录(推荐)