写在前面
因为有这样的一个场景,需要实现竖直方向的多色进度条,然后在网上也找了下,没看到符合需要的,于是自定义了一个,效果如下:
具体实现
本来想定义水平的,然后旋转一下,后来发现还不如直接定义竖直方向来的直接,就直接在竖直方向画了下。
首先讲一下思路,就是通过继承VIEw,然后通过onDraw()方法进行绘制。具体绘制的时候,需要处理一些小细节。
比如,我们需要画一个圆形的滑动块,那么我们的背景色带就不能把整个宽度占满,要不然,小圆块只能和色带一样宽了,效果不是很好看,所以在绘制的时候应该把背景画的宽度小于VIEw的实际宽度。
接下来我要贴代码了:
@OverrIDe protected voID onDraw(Canvas canvas) { super.onDraw(canvas); int h = getMeasuredHeight(); int w = getMeasureDWIDth(); mRadius = (float) w/2; sleft = w * 0.25f; // 背景左边缘坐标 sRight = w * 0.75f;// 背景右边缘坐标 stop = 0; sBottom = h; sWIDth = sRight - sleft; // 背景宽度 sHeight = sBottom - stop; // 背景高度 x = (float) w/2;//圆心的x坐标 y = (float) (1-0.01*progress)*sHeight;//圆心y坐标 drawBackground(canvas); drawCircle(canvas); paint.reset(); }
再看下画背景:
private voID drawBackground(Canvas canvas){ RectF rectBlackBg = new RectF(sleft,stop,sRight,sBottom); linearGradIEnt=new linearGradIEnt(sleft,sWIDth,sHeight,colorArray,null,Shader.TileMode.MIRROR); paint.setAntiAlias(true); paint.setStyle(Paint.Style.FILL); //设置渲染器 paint.setShader(linearGradIEnt); canvas.drawRoundRect(rectBlackBg,sWIDth/2,paint);}
这里使用linearGradIEnt实现多种颜色渐变,默认初始化定义如下:
private int endcolor=color.WHITE; private int thumbcolor=color.BLACK; private int thumbbordercolor=color.WHITE; private int colorArray[]={startcolor,mIDdlecolor,endcolor};
然后看下画圆的 *** 作:
private voID drawCircle(Canvas canvas){ Paint thumbPaint = new Paint(); y = y < mRadius ? mRadius : y;//判断thumb边界 y = y > sHeight-mRadius ? sHeight-mRadius : y; thumbPaint.setAntiAlias(true); thumbPaint.setStyle(Paint.Style.FILL); thumbPaint.setcolor(thumbcolor); canvas.drawCircle(x,y,mRadius,thumbPaint); thumbPaint.setStyle(Paint.Style.stroke); thumbPaint.setcolor(thumbbordercolor); thumbPaint.setstrokeWIDth(2); canvas.drawCircle(x,thumbPaint); }
这里通过画布画了一个圆形,内部填充和外边沿。
上面的过程已经可以使效果展示出来了,但是无法 *** 作,我们还需要给它加上事件才行:
@OverrIDe public boolean ontouchEvent(MotionEvent event) { this.y = event.getY(); progress= (sHeight-y)/sHeight*100; switch(event.getAction()) { case MotionEvent.ACTION_DOWN: break; case MotionEvent.ACTION_UP: if (onStatechangelistener!=null){ onStatechangelistener.onStopTrackingtouch(this,progress); } break; case MotionEvent.ACTION_MOVE: if (onStatechangelistener!=null){ onStatechangelistener.OnStatechangelistener(this,progress); } setProgress(progress); this.invalIDate(); break; } return true; } public interface OnStatechangelistener{ voID OnStatechangelistener(VIEw vIEw,float progress); voID onStopTrackingtouch(VIEw vIEw,float progress); } public voID setonStatechangelistener(OnStatechangelistener onStatechangelistener){ this.onStatechangelistener=onStatechangelistener; }
这里写了个回调接口,然后我们在Activity中就可以接收到相应的滑动进度,进而进行 *** 作,当然,这里我们还得再加一个方法,以便改变seekbar的状态:
public voID setProgress(float progress) { this.progress = progress; invalIDate(); }
到这里,功能基本就OK了,然后我们可以在Activity中去使用它了,下面是布局中的引用:
<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:orIEntation="vertical" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:background="@color/bgcolor" > <include layout="@layout/bar_simple_Title" /> <linearLayout androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:orIEntation="horizontal" androID:gravity="center" > <relativeLayout androID:layout_margintop="20dp" androID:layout_wIDth="wrap_content" androID:layout_height="match_parent" androID:layout_marginRight="35dp" > <TextVIEw androID:ID="@+ID/tv_inner_temper" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:text="@string/inner_temperature" androID:layout_centerHorizontal="true" /> <com.tfxiaozi.Widget.VerticalcolorSeekbar androID:ID="@+ID/vpb_inner_temper" androID:layout_wIDth="20dp" androID:layout_height="300dp" androID:layout_centerHorizontal="true" androID:layout_margintop="30dp"/> <TextVIEw androID:ID="@+ID/tv_current_temper" androID:layout_below="@ID/vpb_inner_temper" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:text="@string/current_temperature" /> </relativeLayout> <relativeLayout androID:layout_marginleft="35dp" androID:layout_margintop="20dp" androID:layout_wIDth="wrap_content" androID:layout_height="match_parent" > <TextVIEw androID:ID="@+ID/tv_brightness" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:text="@string/brightness" androID:layout_centerHorizontal="true" /> <com.tfxiaozi.Widget.VerticalcolorSeekbar androID:ID="@+ID/vpb_brightness" androID:layout_wIDth="20dp" androID:layout_height="300dp" androID:layout_centerHorizontal="true" androID:layout_margintop="30dp"/> <TextVIEw androID:ID="@+ID/tv_current_brightness" androID:layout_below="@ID/vpb_brightness" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:layout_centerHorizontal="true" androID:text="0" /> </relativeLayout> </linearLayout></linearLayout>
怎么使用就很简单了:
package com.tfxiaozi.activity.setting;import androID.graphics.color;import androID.os.Bundle;import androID.vIEw.VIEw;import androID.Widget.ImageVIEw;import androID.Widget.TextVIEw;import com.tfxiaozi.R;import com.tfxiaozi.activity.BaseActivity;import com.tfxiaozi.utils.ToastUtils;import com.tfxiaozi.Widget.VerticalcolorSeekbar;/** * Created by dongqiang on 2016/10/16. */public class ManualSettingActivity extends BaseActivity implements VIEw.OnClickListener,VerticalcolorSeekbar.OnStatechangelistener { private TextVIEw tvCurrentTemper,tvCurrentBrightness,tvMainTitle; private ImageVIEw ivBack; private VerticalcolorSeekbar vpbInnerTemper; private VerticalcolorSeekbar vpbBrightness; @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_manual_setting); initVIEws(); initEvents(); initData(); } private voID initVIEws() { tvMainTitle = (TextVIEw) findVIEwByID(R.ID.Title_main_text); tvMainTitle.setText(getString(R.string.manual_setting)); tvMainTitle.setVisibility(VIEw.VISIBLE); ivBack = (ImageVIEw) findVIEwByID(R.ID.Title_back); ivBack.setVisibility(VIEw.VISIBLE); tvCurrentTemper = (TextVIEw) findVIEwByID(R.ID.tv_current_temper); tvCurrentBrightness = (TextVIEw) findVIEwByID(R.ID.tv_current_brightness); vpbInnerTemper = (VerticalcolorSeekbar)findVIEwByID(R.ID.vpb_inner_temper); vpbBrightness = (VerticalcolorSeekbar) findVIEwByID(R.ID.vpb_brightness); vpbInnerTemper.setcolor(color.RED,color.YELLOW,color.GREEN,color.BLUE,color.transparent); vpbBrightness.setcolor(color.BLUE,color.WHITE,color.transparent); } private voID initEvents() { ivBack.setonClickListener(this); vpbInnerTemper.setonStatechangelistener(this); vpbBrightness.setonStatechangelistener(this); } private voID initData() { vpbInnerTemper.setProgress(50); vpbBrightness.setProgress(70); } @OverrIDe public voID onClick(VIEw v) { switch (v.getID()) { case R.ID.Title_back: finish(); break; } } @OverrIDe public voID OnStatechangelistener(VIEw vIEw,float progress) { } @OverrIDe public voID onStopTrackingtouch(VIEw vIEw,float progress) { int vIEwID = vIEw.getID(); switch (vIEwID) { case R.ID.vpb_inner_temper: if (progress < 0) { progress = 0; } if(progress > 100) { progress = 100; } ToastUtils.showShort(this,"progress= " + progress); break; case R.ID.vpb_brightness: if (progress < 0) { progress = 0; } if(progress > 100) { progress = 100; } ToastUtils.showShort(this,"progress1= " + progress); break; } }}
到这里就结束了,最后还是附上自定义view的整个代码吧:
package com.tfxiaozi.Widget;import androID.content.Context;import androID.graphics.Canvas;import androID.graphics.color;import androID.graphics.linearGradIEnt;import androID.graphics.Paint;import androID.graphics.RectF;import androID.graphics.Shader;import androID.util.AttributeSet;import androID.util.Log;import androID.vIEw.MotionEvent;import androID.vIEw.VIEw;/** * Created by dongqiang on 2016/10/21. */public class VerticalcolorSeekbar extends VIEw{ private static final String TAG = VerticalcolorSeekbar.class.getSimplename(); private int startcolor= color.BLACK; private int mIDdlecolor = color.GRAY; private int endcolor=color.WHITE; private int thumbcolor=color.BLACK; private int thumbbordercolor=color.WHITE; private int colorArray[]={startcolor,endcolor}; private float x,y; private float mRadius; private float progress; private float maxCount = 100f; private float sleft,sBottom; private float sWIDth,sHeight; private linearGradIEnt linearGradIEnt; private Paint paint = new Paint(); protected OnStatechangelistener onStatechangelistener; public VerticalcolorSeekbar(Context context) { this(context,null); } public VerticalcolorSeekbar(Context context,AttributeSet attrs) { super(context,attrs); } @OverrIDe protected synchronized voID onMeasure(int wIDthMeasureSpec,int heightmeasureSpec) { super.onMeasure(wIDthMeasureSpec,heightmeasureSpec); setMeasuredDimension(getMeasureDWIDth(),getMeasuredHeight()); } public voID setcolor(int startcolor,int mIDdlecolor,int endcolor,int thumbcolor,int thumbbordercolor){ this.startcolor= startcolor; this.mIDdlecolor = mIDdlecolor; this.endcolor= endcolor; this.thumbcolor= thumbcolor; this.thumbbordercolor= thumbbordercolor; colorArray[0] = startcolor; colorArray[1] = mIDdlecolor; colorArray[2] = endcolor; } @OverrIDe protected voID onDraw(Canvas canvas) { super.onDraw(canvas); int h = getMeasuredHeight(); int w = getMeasureDWIDth(); mRadius = (float) w/2; sleft = w * 0.25f; // 背景左边缘坐标 sRight = w * 0.75f;// 背景右边缘坐标 stop = 0; sBottom = h; sWIDth = sRight - sleft; // 背景宽度 sHeight = sBottom - stop; // 背景高度 x = (float) w/2;//圆心的x坐标 y = (float) (1-0.01*progress)*sHeight;//圆心y坐标 drawBackground(canvas); drawCircle(canvas); paint.reset(); } private voID drawBackground(Canvas canvas){ RectF rectBlackBg = new RectF(sleft,paint); } private voID drawCircle(Canvas canvas){ Paint thumbPaint = new Paint(); y = y < mRadius ? mRadius : y;//判断thumb边界 y = y > sHeight-mRadius ? sHeight-mRadius : y; thumbPaint.setAntiAlias(true); thumbPaint.setStyle(Paint.Style.FILL); thumbPaint.setcolor(thumbcolor); canvas.drawCircle(x,thumbPaint); } @OverrIDe public boolean ontouchEvent(MotionEvent event) { this.y = event.getY(); progress= (sHeight-y)/sHeight*100; switch(event.getAction()) { case MotionEvent.ACTION_DOWN: break; case MotionEvent.ACTION_UP: if (onStatechangelistener!=null){ onStatechangelistener.onStopTrackingtouch(this,progress); } setProgress(progress); this.invalIDate(); break; } return true; } public interface OnStatechangelistener{ voID OnStatechangelistener(VIEw vIEw,float progress); } public voID setonStatechangelistener(OnStatechangelistener onStatechangelistener){ this.onStatechangelistener=onStatechangelistener; } public voID setProgress(float progress) { this.progress = progress; invalIDate(); }}
结束
到这里就真的结束啦,就当记录一下吧,然后也希望帮到有需要的人。有更好的实现也可以告诉我哈~
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
总结以上是内存溢出为你收集整理的Android自定义竖直方向SeekBar多色进度条全部内容,希望文章能够帮你解决Android自定义竖直方向SeekBar多色进度条所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)