Android   发布时间:2022-04-28  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Android自定义竖直方向SeekBar多色进度条大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

写在前面

因为有这样的一个场景,需要实现竖直方向的多色进度条,然后在网上也找了下,没看到符合需要的,于是自定义一个效果如下:

Android自定义竖直方向SeekBar多色进度条

具体实现

本来想定义水平的,然后旋转一下,后来发现还不如直接定义竖直方向来的直接,就直接在竖直方向画了下。

首先讲一下思路,就是通过继承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.@L_616_9@);
  thumbPaint.setColor(thumbBorderColor);
  thumbPaint.set@L_616_9@Width(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://scheR_416_11845@as.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多色进度条所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签:进度条