900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > Android 自定义控件 仿MX 播放器的SeekBar效果

Android 自定义控件 仿MX 播放器的SeekBar效果

时间:2019-08-29 09:38:56

相关推荐

Android 自定义控件 仿MX 播放器的SeekBar效果

一、分析

最近下载了个MX 播放器来看视频,发现他的SeekBar做的挺有趣的,先看看MX 播放器的SeekBar效果:

外面多了个框框,没有了进度的那个小圆点,还可以以水平方向的摆放和竖直方向的摆放,也可以改颜色。这种效果可以通过自己实现onDraw()方法然后画个方框里面再画一条线。

根据以上特征我们可以在SeekBar基础上进行修改,毕竟SeekBar已经有了很多属性以及实现了拖动效果,就没必要重头造轮子了。

看看实现的效果吧,所谓No picture you say shen ma。

二、实现

(一)自定义属性

<?xml version="1.0" encoding="utf-8"?><resources><!--外框线的大小--><attr name="rect_line_width" format="dimension" /><!--外框线的颜色--><attr name="rect_color" format="color" /><!--进度条与外框的间距--><attr name="padding_rect" format="dimension" /><!--进度条的粗细--><attr name="progress_stroke_width" format="dimension" /><!--进度条的颜色--><attr name="progress_color" format="color" /><!--缓冲进度条的颜色--><attr name="secondary_progress_color" format="color" /><!--进度条的方向--><attr name="orientation" format="enum"><enum name="horizontal" value="0" /><enum name="vartical" value="1"/></attr><declare-styleable name="CustomSeekBar"><attr name="rect_line_width" /><attr name="rect_color" /><attr name="padding_rect" /><attr name="progress_stroke_width" /><attr name="progress_color" /><attr name="secondary_progress_color" /><attr name="orientation" /></declare-styleable></resources>

(二)解析属性

private final static int DEFAULT_RECT_LINE_WIDTH=0;private final static int DEFAULT_RECT_COLOR=ColorStateList.valueOf(0x66000000).getDefaultColor();private final static int DEFAULT_PADDING_RECT=2;private final static int DEFAULT_PROGRESS_HEIGHT=30;private final static int DEFAULT_PROGRESS_COLOR=ColorStateList.valueOf(0xFF58ccff).getDefaultColor();private final static int DEFAULT_SECONDARY_PROGRESS_COLOR=ColorStateList.valueOf(0x22000000).getDefaultColor();/*** Seek bar的方向*/public enum Orientation {HORIZONTAL, VARTICAL}private Context mContext;/*** 外边框线的大小*/private int mRectLineWidth=DEFAULT_RECT_LINE_WIDTH;/*** 外边框线的颜色*/private int mRectColor=DEFAULT_RECT_COLOR;/*** 里面的进度条与外边框的距离*/private int mPaddingRect=dp2px(DEFAULT_PADDING_RECT);/*** 进度条的粗细*/private int mProgressStrokeWidth=dp2px(DEFAULT_PROGRESS_HEIGHT);/*** 进度条的颜色*/private int mProgressColor=DEFAULT_PROGRESS_COLOR;/*** 缓冲进度条的颜色*/private int mSecondaryProgressColor=DEFAULT_SECONDARY_PROGRESS_COLOR;/*** Seek bar的方向 默认为水平方向*/private Orientation mOrientation=Orientation.HORIZONTAL;/*** Seek bar真实的宽度*/private int mRealWidth;/*** Seek bar真实的高度*/private int mRealHeight;/*** 画笔*/private Paint mPaint;public CustomSeekBar(Context context) {this(context, null);}public CustomSeekBar(Context context, AttributeSet attrs) {this(context, attrs, 0);}public CustomSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);this.mContext=context;parseAttr(attrs, defStyleAttr);mPaint=new Paint();mPaint.setAntiAlias(true);}/*** 解析属性** @param attrs AttributeSet* @param defStyleAttr defStyleAttr*/private void parseAttr(AttributeSet attrs, int defStyleAttr) {TypedArray _TypedArray=mContext.obtainStyledAttributes(attrs, R.styleable.CustomSeekBar, defStyleAttr, 0);int _Count=_TypedArray.getIndexCount();for (int i=0; i < _Count; i++) {int _Index=_TypedArray.getIndex(i);switch (_Index) {case R.styleable.CustomSeekBar_rect_line_width:mRectLineWidth=_TypedArray.getDimensionPixelSize(_Index, DEFAULT_RECT_LINE_WIDTH);break;case R.styleable.CustomSeekBar_rect_color:mRectColor=_TypedArray.getColor(_Index, DEFAULT_RECT_COLOR);break;case R.styleable.CustomSeekBar_padding_rect:mPaddingRect=_TypedArray.getDimensionPixelSize(_Index, dp2px(DEFAULT_PADDING_RECT));break;case R.styleable.CustomSeekBar_progress_stroke_width:mProgressStrokeWidth=_TypedArray.getDimensionPixelSize(_Index, dp2px(DEFAULT_PROGRESS_HEIGHT));break;case R.styleable.CustomSeekBar_progress_color:mProgressColor=_TypedArray.getColor(_Index, DEFAULT_PROGRESS_COLOR);break;case R.styleable.CustomSeekBar_secondary_progress_color:mSecondaryProgressColor=_TypedArray.getColor(_Index, DEFAULT_SECONDARY_PROGRESS_COLOR);break;case R.styleable.CustomSeekBar_orientation:int _Orientation=_TypedArray.getInt(_Index, 0);if (_Orientation == 0) {mOrientation=Orientation.HORIZONTAL;} else {mOrientation=Orientation.VARTICAL;}break;}}_TypedArray.recycle();}

private int dp2px(int pDpVal){return (int) TypedValue.applyDimension(PLEX_UNIT_DIP, pDpVal, getResources().getDisplayMetrics());}

解析属性就没什么好说的了。

(三)覆盖onMeasure()方法修改宽度或高度

@Overrideprotected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {if (mOrientation == Orientation.HORIZONTAL) {int _HeightMode=MeasureSpec.getMode(heightMeasureSpec);if (_HeightMode != MeasureSpec.EXACTLY) {//进度条的高度 + 上下两边与外边框的距离 + 上下外边框的线的大小 + 上下paddingint _Height=mProgressStrokeWidth + (mPaddingRect * 2) + (mRectLineWidth * 2)+ getPaddingTop() + getPaddingBottom();heightMeasureSpec=MeasureSpec.makeMeasureSpec(_Height, MeasureSpec.EXACTLY);}} else {int _WidthMode=MeasureSpec.getMode(widthMeasureSpec);if (_WidthMode != MeasureSpec.EXACTLY) {//进度条的宽度 + 左右两边与外边框的距离 + 左右外边框的线的大小 + 左右paddingint _Width=mProgressStrokeWidth + (mPaddingRect * 2) + (mRectLineWidth * 2)+ getPaddingLeft() + getPaddingRight();widthMeasureSpec=MeasureSpec.makeMeasureSpec(_Width, MeasureSpec.EXACTLY);}}super.onMeasure(widthMeasureSpec, heightMeasureSpec);}

如果是EXACTLY模式,我们就不需要处理了,其他的我们就需要重新计算下宽度或高度。

(四)获取SeekBar真实的宽度和高度

@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);//宽度 - 左右两边paddingmRealWidth=w - getPaddingLeft() - getPaddingRight();//高度 - 上下两边paddingmRealHeight=h - getPaddingTop() - getPaddingBottom();}

(四)画水平SeekBar外面的边框

/*** 画横向的外面的边框* @param canvas Canvas*/private void drawHorizontalRect(Canvas canvas) {if (mRectLineWidth <= 0) return;canvas.save();//把坐标原点移到进度条左边的垂直中间位置canvas.translate(getPaddingLeft(), getHeight() / 2.0f);mPaint.setStyle(Paint.Style.STROKE);mPaint.setStrokeWidth(mRectLineWidth);mPaint.setColor(mRectColor);//根据坐标原点计算左上右下的位置float _Left=mRectLineWidth / 2.0f;float _Top=-(mRealHeight / 2.0f - (mRectLineWidth / 2.0f));float _Right=mRealWidth - (mRectLineWidth / 2.0f);float _Bottom=mRealHeight / 2.0f - (mRectLineWidth / 2.0f);canvas.drawRect(_Left, _Top, _Right, _Bottom, mPaint);canvas.restore();}

为了方便计算,我们把原点移动到左边的垂直中间的位置,计算出方框左上右下的位置,然后画上,结合下图理解。

(五)画水平SeekBar的进度条

/*** 画横向进度条** @param canvas Canvas*/private void drawHorizontalProgress(Canvas canvas) {if (mProgressStrokeWidth <= 0) return;canvas.save();//将坐标原点移到进度条左边中间的位置canvas.translate(getPaddingLeft() + mRectLineWidth + mPaddingRect, getHeight() / 2);//缓冲进度条所占总进度的百分比float _SecondaryPercentage=(float) getSecondaryProgress() / getMax();//进度条的总宽度float _TotalProgressWidth=mRealWidth - (2 * mRectLineWidth + 2 * mPaddingRect);//缓冲进度条的宽度float _SecondaryReachWidth=_TotalProgressWidth * _SecondaryPercentage;mPaint.setStyle(Paint.Style.FILL);mPaint.setColor(mSecondaryProgressColor);mPaint.setStrokeWidth(mProgressStrokeWidth);canvas.drawLine(0, 0, _SecondaryReachWidth, 0, mPaint);//进度条所占总进度的百分比float _Percentage=(float) getProgress() / getMax();//进度条的宽度float _ReachWidth=_TotalProgressWidth * _Percentage;mPaint.setColor(mProgressColor);canvas.drawLine(0, 0, _ReachWidth, 0, mPaint);canvas.restore();}

我们又将坐标原点移动了,进度条可以用画线进行,计算出线的起始x和y的位置和结束的x和y的位置然后进行绘画,结合下图理解。

(六)画垂直Seekbar外面的边框

/*** 画纵向的外边框* @param canvas Canvas*/private void drawVertacalRect(Canvas canvas) {if (mRectLineWidth <= 0) return;canvas.save();//将坐标原点移到SeekBar的底部中间canvas.translate(getWidth() / 2.0f, getHeight() - getPaddingBottom() - (mRectLineWidth / 2.0f));mPaint.setStyle(Paint.Style.STROKE);mPaint.setStrokeWidth(mRectLineWidth);mPaint.setColor(mRectColor);//根据坐标原点计算左上右下的位置float _Left=-(mRealWidth / 2.0f - (mRectLineWidth / 2.0f));float _Top=-(mRealHeight - (mRectLineWidth));float _Right=mRealWidth / 2.0f - (mRectLineWidth / 2.0f);float _Bottom=0;canvas.drawRect(_Left, _Top, _Right, _Bottom, mPaint);canvas.restore();}

这次是画垂直方向的方框了,照样移动坐标原点,然后计算出方框的左上右下的位置进行绘画。

(七)画垂直SeekBar的进度条

/*** 画纵向的进度条* @param canvas Canvas*/private void drawVertacalProgress(Canvas canvas) {if (mProgressStrokeWidth <= 0) return;canvas.save();//把坐标原点移到进度条底部的中间canvas.translate(getWidth() / 2.0f, getHeight() - getPaddingBottom() - mRectLineWidth - mPaddingRect);//缓冲进度条所占总进度的百分比float _SecondaryPercentage=(float) getSecondaryProgress() / getMax();//进度条的总高度float _TotalProgressWidth=mRealHeight - (2 * mRectLineWidth + 2 * mPaddingRect);//缓冲进度条的高度float _SecondaryReachWidth=_TotalProgressWidth * _SecondaryPercentage;mPaint.setStyle(Paint.Style.FILL);mPaint.setColor(mSecondaryProgressColor);mPaint.setStrokeWidth(mProgressStrokeWidth);canvas.drawLine(0, 0, 0, -_SecondaryReachWidth, mPaint);//进度条所占总进度的百分比float _Percentage=(float) getProgress() / getMax();//进度条的高度float _ReachWidth=_TotalProgressWidth * _Percentage;mPaint.setColor(mProgressColor);canvas.drawLine(0, 0, 0, -_ReachWidth, mPaint);canvas.restore();}

为了方便,同样要改变下坐标原点,计算出线的起始x和y的位置和结束的x和y的位置然后进行画线,位置看下图。

(八)覆盖onDraw()方法

基本的已经完成的差不多了,覆盖onDraw()方法调用刚才定义的方法。

@Overrideprotected synchronized void onDraw(Canvas canvas) {if (mOrientation == Orientation.HORIZONTAL) {drawHorizontalRect(canvas);drawHorizontalProgress(canvas);} else {drawVertacalRect(canvas);drawVertacalProgress(canvas);}}

到这里效果已经出来了,但是还有一个问题,就是垂直方向的SeekBar拖动还没解决,在垂直方向的SeekBar上你会发现点击和上下滑动是没效果的,只能左右滑动,毕竟SeekBar本身就是左右滑动的,这时我们需要覆盖onTouchEvent()方法实现垂直方向上的SeekBar上下滑动也有效果。

(九)解决垂直方向的SeekBar的点击和上下滑动问题

@Overridepublic boolean onTouchEvent(MotionEvent event) {//如果是纵向的就把触摸事件拦截下来,如果是横向的就用系统的if (mOrientation == Orientation.VARTICAL) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:case MotionEvent.ACTION_MOVE:case MotionEvent.ACTION_UP:int _Progress=0;//总大小 - 触摸时的高度与总高度比例换算成所占进度条的进度_Progress=getMax() - (int) (getMax() * (event.getY() / getHeight()));setProgress(_Progress);break;case MotionEvent.ACTION_CANCEL:break;}return true;}return super.onTouchEvent(event);}

覆盖onTouchEvent()方法,对于Action不是ACTION_CANCEL进行处理,用进度条的最大值减去触摸时的高度与总高度比例换算成所占进度条的进度,因为现在我们的进度条是从下到上的,坐标Y是从上到下的,所以要用getY()和高度的比。

(十)完整的代码

package com.ce.customseekbar;import android.content.Context;import android.content.res.ColorStateList;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Paint;import android.util.AttributeSet;import android.util.TypedValue;import android.view.MotionEvent;import android.widget.SeekBar;public class CustomSeekBar extends SeekBar {private final static int DEFAULT_RECT_LINE_WIDTH=0;private final static int DEFAULT_RECT_COLOR=ColorStateList.valueOf(0x66000000).getDefaultColor();private final static int DEFAULT_PADDING_RECT=2;private final static int DEFAULT_PROGRESS_HEIGHT=30;private final static int DEFAULT_PROGRESS_COLOR=ColorStateList.valueOf(0xFF58ccff).getDefaultColor();private final static int DEFAULT_SECONDARY_PROGRESS_COLOR=ColorStateList.valueOf(0x22000000).getDefaultColor();/*** Seek bar的方向*/public enum Orientation {HORIZONTAL, VARTICAL}private Context mContext;/*** 外边框线的大小*/private int mRectLineWidth=DEFAULT_RECT_LINE_WIDTH;/*** 外边框线的颜色*/private int mRectColor=DEFAULT_RECT_COLOR;/*** 里面的进度条与外边框的距离*/private int mPaddingRect=dp2px(DEFAULT_PADDING_RECT);/*** 进度条的粗细*/private int mProgressStrokeWidth=dp2px(DEFAULT_PROGRESS_HEIGHT);/*** 进度条的颜色*/private int mProgressColor=DEFAULT_PROGRESS_COLOR;/*** 缓冲进度条的颜色*/private int mSecondaryProgressColor=DEFAULT_SECONDARY_PROGRESS_COLOR;/*** Seek bar的方向 默认为水平方向*/private Orientation mOrientation=Orientation.HORIZONTAL;/*** Seek bar真实的宽度*/private int mRealWidth;/*** Seek bar真实的高度*/private int mRealHeight;/*** 画笔*/private Paint mPaint;public CustomSeekBar(Context context) {this(context, null);}public CustomSeekBar(Context context, AttributeSet attrs) {this(context, attrs, 0);}public CustomSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);this.mContext=context;parseAttr(attrs, defStyleAttr);mPaint=new Paint();mPaint.setAntiAlias(true);}/*** 解析属性** @param attrs AttributeSet* @param defStyleAttr defStyleAttr*/private void parseAttr(AttributeSet attrs, int defStyleAttr) {TypedArray _TypedArray=mContext.obtainStyledAttributes(attrs, R.styleable.CustomSeekBar, defStyleAttr, 0);int _Count=_TypedArray.getIndexCount();for (int i=0; i < _Count; i++) {int _Index=_TypedArray.getIndex(i);switch (_Index) {case R.styleable.CustomSeekBar_rect_line_width:mRectLineWidth=_TypedArray.getDimensionPixelSize(_Index, DEFAULT_RECT_LINE_WIDTH);break;case R.styleable.CustomSeekBar_rect_color:mRectColor=_TypedArray.getColor(_Index, DEFAULT_RECT_COLOR);break;case R.styleable.CustomSeekBar_padding_rect:mPaddingRect=_TypedArray.getDimensionPixelSize(_Index, dp2px(DEFAULT_PADDING_RECT));break;case R.styleable.CustomSeekBar_progress_stroke_width:mProgressStrokeWidth=_TypedArray.getDimensionPixelSize(_Index, dp2px(DEFAULT_PROGRESS_HEIGHT));break;case R.styleable.CustomSeekBar_progress_color:mProgressColor=_TypedArray.getColor(_Index, DEFAULT_PROGRESS_COLOR);break;case R.styleable.CustomSeekBar_secondary_progress_color:mSecondaryProgressColor=_TypedArray.getColor(_Index, DEFAULT_SECONDARY_PROGRESS_COLOR);break;case R.styleable.CustomSeekBar_orientation:int _Orientation=_TypedArray.getInt(_Index, 0);if (_Orientation == 0) {mOrientation=Orientation.HORIZONTAL;} else {mOrientation=Orientation.VARTICAL;}break;}}_TypedArray.recycle();}@Overrideprotected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {if (mOrientation == Orientation.HORIZONTAL) {int _HeightMode=MeasureSpec.getMode(heightMeasureSpec);if (_HeightMode != MeasureSpec.EXACTLY) {//进度条的高度 + 上下两边与外边框的距离 + 上下外边框的线的大小 + 上下paddingint _Height=mProgressStrokeWidth + (mPaddingRect * 2) + (mRectLineWidth * 2)+ getPaddingTop() + getPaddingBottom();heightMeasureSpec=MeasureSpec.makeMeasureSpec(_Height, MeasureSpec.EXACTLY);}} else {int _WidthMode=MeasureSpec.getMode(widthMeasureSpec);if (_WidthMode != MeasureSpec.EXACTLY) {//进度条的宽度 + 左右两边与外边框的距离 + 左右外边框的线的大小 + 左右paddingint _Width=mProgressStrokeWidth + (mPaddingRect * 2) + (mRectLineWidth * 2)+ getPaddingLeft() + getPaddingRight();widthMeasureSpec=MeasureSpec.makeMeasureSpec(_Width, MeasureSpec.EXACTLY);}}super.onMeasure(widthMeasureSpec, heightMeasureSpec);}@Overrideprotected synchronized void onDraw(Canvas canvas) {if (mOrientation == Orientation.HORIZONTAL) {drawHorizontalRect(canvas);drawHorizontalProgress(canvas);} else {drawVertacalRect(canvas);drawVertacalProgress(canvas);}}/*** 画纵向的进度条* @param canvas Canvas*/private void drawVertacalProgress(Canvas canvas) {if (mProgressStrokeWidth <= 0) return;canvas.save();//把坐标原点移到进度条底部的中间canvas.translate(getWidth() / 2.0f, getHeight() - getPaddingBottom() - mRectLineWidth - mPaddingRect);//缓冲进度条所占总进度的百分比float _SecondaryPercentage=(float) getSecondaryProgress() / getMax();//进度条的总高度float _TotalProgressWidth=mRealHeight - (2 * mRectLineWidth + 2 * mPaddingRect);//缓冲进度条的高度float _SecondaryReachWidth=_TotalProgressWidth * _SecondaryPercentage;mPaint.setStyle(Paint.Style.FILL);mPaint.setColor(mSecondaryProgressColor);mPaint.setStrokeWidth(mProgressStrokeWidth);canvas.drawLine(0, 0, 0, -_SecondaryReachWidth, mPaint);//进度条所占总进度的百分比float _Percentage=(float) getProgress() / getMax();//进度条的高度float _ReachWidth=_TotalProgressWidth * _Percentage;mPaint.setColor(mProgressColor);canvas.drawLine(0, 0, 0, -_ReachWidth, mPaint);canvas.restore();}/*** 画纵向的外边框* @param canvas Canvas*/private void drawVertacalRect(Canvas canvas) {if (mRectLineWidth <= 0) return;canvas.save();//将坐标原点移到SeekBar的底部中间canvas.translate(getWidth() / 2.0f, getHeight() - getPaddingBottom() - (mRectLineWidth / 2.0f));mPaint.setStyle(Paint.Style.STROKE);mPaint.setStrokeWidth(mRectLineWidth);mPaint.setColor(mRectColor);//根据坐标原点计算左上右下的位置float _Left=-(mRealWidth / 2.0f - (mRectLineWidth / 2.0f));float _Top=-(mRealHeight - (mRectLineWidth));float _Right=mRealWidth / 2.0f - (mRectLineWidth / 2.0f);float _Bottom=0;canvas.drawRect(_Left, _Top, _Right, _Bottom, mPaint);canvas.restore();}/*** 画横向进度条** @param canvas Canvas*/private void drawHorizontalProgress(Canvas canvas) {if (mProgressStrokeWidth <= 0) return;canvas.save();//将坐标原点移到进度条左边中间的位置canvas.translate(getPaddingLeft() + mRectLineWidth + mPaddingRect, getHeight() / 2);//缓冲进度条所占总进度的百分比float _SecondaryPercentage=(float) getSecondaryProgress() / getMax();//进度条的总宽度float _TotalProgressWidth=mRealWidth - (2 * mRectLineWidth + 2 * mPaddingRect);//缓冲进度条的宽度float _SecondaryReachWidth=_TotalProgressWidth * _SecondaryPercentage;mPaint.setStyle(Paint.Style.FILL);mPaint.setColor(mSecondaryProgressColor);mPaint.setStrokeWidth(mProgressStrokeWidth);canvas.drawLine(0, 0, _SecondaryReachWidth, 0, mPaint);//进度条所占总进度的百分比float _Percentage=(float) getProgress() / getMax();//进度条的宽度float _ReachWidth=_TotalProgressWidth * _Percentage;mPaint.setColor(mProgressColor);canvas.drawLine(0, 0, _ReachWidth, 0, mPaint);canvas.restore();}/*** 画横向的外面的边框* @param canvas Canvas*/private void drawHorizontalRect(Canvas canvas) {if (mRectLineWidth <= 0) return;canvas.save();//把坐标原点移到进度条左边的垂直中间位置canvas.translate(getPaddingLeft(), getHeight() / 2.0f);mPaint.setStyle(Paint.Style.STROKE);mPaint.setStrokeWidth(mRectLineWidth);mPaint.setColor(mRectColor);//根据坐标原点计算左上右下的位置float _Left=mRectLineWidth / 2.0f;float _Top=-(mRealHeight / 2.0f - (mRectLineWidth / 2.0f));float _Right=mRealWidth - (mRectLineWidth / 2.0f);float _Bottom=mRealHeight / 2.0f - (mRectLineWidth / 2.0f);canvas.drawRect(_Left, _Top, _Right, _Bottom, mPaint);canvas.restore();}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);//宽度 - 左右两边paddingmRealWidth=w - getPaddingLeft() - getPaddingRight();//高度 - 上下两边paddingmRealHeight=h - getPaddingTop() - getPaddingBottom();}@Overridepublic boolean onTouchEvent(MotionEvent event) {//如果是纵向的就把触摸事件拦截下来,如果是横向的就用系统的if (mOrientation == Orientation.VARTICAL) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:case MotionEvent.ACTION_MOVE:case MotionEvent.ACTION_UP:int _Progress=0;//总大小 - 触摸时的高度与总高度比例换算成所占进度条的进度_Progress=getMax() - (int) (getMax() * (event.getY() / getHeight()));setProgress(_Progress);break;case MotionEvent.ACTION_CANCEL:break;}return true;}return super.onTouchEvent(event);}private int dp2px(int pDpVal){return (int) TypedValue.applyDimension(PLEX_UNIT_DIP, pDpVal,getResources().getDisplayMetrics());}}

三、使用

(一)布局

<?xml version="1.0" encoding="utf-8"?><RelativeLayoutxmlns:android="/apk/res/android"xmlns:tools="/tools"xmlns:app="/apk/res-auto"android:id="@+id/activity_main"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="horizontal"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"android:paddingBottom="@dimen/activity_vertical_margin"tools:context="com.ce.customseekbar.MainActivity"><com.ce.customseekbar.CustomSeekBarandroid:id="@+id/custom_seek_bar_hor"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:paddingTop="5dp"android:layout_marginTop="10dp"app:rect_line_width="1dp"app:padding_rect="2dp"app:progress_color="#CC6ba3d0"app:progress_stroke_width="20dp"app:rect_color="#33000000"app:secondary_progress_color="#22000000"app:orientation="horizontal"android:max="100"android:progress="50"android:secondaryProgress="70"/><com.ce.customseekbar.CustomSeekBarandroid:id="@+id/custom_seek_bar"android:layout_width="wrap_content"android:layout_height="200dp"android:layout_centerVertical="true"app:rect_line_width="1dp"app:padding_rect="2dp"app:progress_color="#CCFFAA00"app:progress_stroke_width="20dp"app:rect_color="#33000000"app:orientation="vartical"android:max="100"android:progress="50"/></RelativeLayout>

(二)Activity

package com.ce.customseekbar;import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;public class MainActivity extends AppCompatActivity {private CustomSeekBar mHorCustomSeekBar;private CustomSeekBar mCustomSeekBar;private int mHorProgress = 0;private int mProgress = 0;private int mSecondaryProgress = 0;private final static int WHAT_UPDATE_HOR_PROGRESS = 1000;private final static int WHAT_UPDATE_VER_PROGRESS = WHAT_UPDATE_HOR_PROGRESS + 1;private android.os.Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {int _What = msg.what;switch (_What) {case WHAT_UPDATE_HOR_PROGRESS:if (mHorProgress < 100) {if (mSecondaryProgress < 100) {mSecondaryProgress += 2;mHorCustomSeekBar.setSecondaryProgress(mSecondaryProgress);}mHorCustomSeekBar.setProgress(++mHorProgress);mHandler.sendEmptyMessageDelayed(WHAT_UPDATE_HOR_PROGRESS, 50);}break;case WHAT_UPDATE_VER_PROGRESS:if (mProgress < 100) {mCustomSeekBar.setProgress(++mProgress);mHandler.sendEmptyMessageDelayed(WHAT_UPDATE_VER_PROGRESS, 50);}break;}}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mHorCustomSeekBar =(CustomSeekBar) findViewById(R.id.custom_seek_bar_hor);mCustomSeekBar =(CustomSeekBar) findViewById(R.id.custom_seek_bar);mHandler.sendEmptyMessageDelayed(WHAT_UPDATE_HOR_PROGRESS, 50);mHandler.sendEmptyMessageDelayed(WHAT_UPDATE_VER_PROGRESS, 50);}@Overrideprotected void onDestroy() {mHandler.removeMessages(WHAT_UPDATE_HOR_PROGRESS);mHandler.removeMessages(WHAT_UPDATE_VER_PROGRESS);super.onDestroy();}}

源码地址

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。