前言
由于最近做tv开发,写了一个基于播放器上的seekbar,感觉还是蛮整洁大方的。给大家分享下。
效果图
时间的总长暂定30分钟。
思路
1.需要一个图片,一个文字,图片中心对着seekbar的当前进度下面
2.文字在图片下面
3.随着seekbar的进度改变,图片位置改变、文字地址、值改变。
一、重写seekbar,然后添加图片
public TVSeekBar(Context context) {
this(context,null);
}
public TVSeekBar(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public TVSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
mTextSize = dp2px(20);
getImgWH();
mPaint = new Paint();
mPaint.setTextSize(mTextSize);//设置文字大小
mPaint.setColor(mTextColor);//设置文字颜色
//设置控件的padding 给提示文字留出位置
setPadding((int) Math.ceil(img_width) / 2, 0, (int) Math.ceil(img_height) / 2, (int) Math.ceil(img_height) + 10);
}
封装出来的方法:
/**
* 获取图片宽高
*/
private void getImgWH() {
map = BitmapFactory.decodeResource(getResources(), R.mipmap.playing_icon_arow);
img_width = map.getWidth();
img_height = map.getHeight();
}
二、对着seekbar的进度(getprogress)的改变而变换位置和值
重写ondraw方法。这里draw和ondraw的区别,简单来说就是 draw包含ondraw()
@Override
protected synchronized void onDraw(Canvas canvas) {
super.onDraw(canvas);
rect_seek = this.getProgressDrawable().getBounds();
setTextLocation();//定位文本绘制的位置
//定位文字背景图片的位置
float bm_x = rect_seek.width() * getProgress() / getMax();
float bm_y = rect_seek.height() + 2;
//计算文字的中心位置在bitmap
float text_x = rect_seek.width() * getProgress() / getMax() + (img_width - numTextWidth) / 2;
Matrix matrix = new Matrix();
//canvas.drawBitmap(map, bm_x, bm_y, paint);//画背景图
matrix.postScale(0.5f, 0.5f);
matrix.postTranslate(bm_x + img_width / 4, 15);
canvas.drawBitmap(map, matrix, mPaint);
mPaint.setTypeface(Typeface.DEFAULT_BOLD);
//设置锯齿 否则字体会模糊
mPaint.setAntiAlias(true);
canvas.drawText(mText, text_x, 50, mPaint);
}
这里主要坐下排版 9:3 ---->09:03 好看点
/**
* 不断更新文字的文字
*/
private void setTextLocation() {
fm = mPaint.getFontMetrics();
int progress = getProgress();
numTextWidth = mPaint.measureText(mText);
int time=progress * 30 *60 /1000;
String hour=time/60+"";
String min=time%60+"";
if(hour.length()<2){
hour="0"+hour;
}
if(min.length()<2){
min="0"+min;
}
mText=hour+":"+min;
}
dp和px之间转换的工具类
public int dp2px(float dpValue) {
float scale = mContext.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
这样就重写完整啦。在布局文件中的使用:
<com.maxence.tvseekbar.TVSeekBar
android:id="@+id/sk_bar"
android:layout_width="match_parent"
android:layout_height="40dp"
android:max="1000"
android:progress="100"
android:progressDrawable="@drawable/bg_seekbar_progress_drawable"
android:secondaryProgress="300"
android:thumb="@null"
/>
下面附上seekbar的样式,有进度颜色、背景颜色和二级进度条的颜色,二级进度条普遍用于视频中缓存视频的进度
bg_seekbar_progress_drawable.xml
?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 底部背景 -->
<item android:id="@android:id/background" android:height="3dp">
<shape>
<corners android:radius="5dp"/>
<size android:height="10dp" />
<solid android:color="#505050"/>
</shape>
</item>
<!--缓冲进度-->
<item android:id="@android:id/secondaryProgress" android:height="3dp">
<clip>
<shape>
<corners android:radius="5dp"/>
<size android:height="10dp" />
<solid android:color="#858585"/>
</shape>
</clip>
</item>
<!-- 进度背景 00ade6-->
<item android:id="@android:id/progress" android:height="3dp">
<clip>
<shape>
<corners android:radius="5dp"/>
<size android:height="10dp" />
<solid android:color="#0485e0"/>
</shape>
</clip>
</item>
</layer-list>
这样就ok了
下载地址:github的tvseekbar
csdn : 下载