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

写在前面

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

具体实现

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

首先讲一下思路,就是通过继承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,sTop,sWidth,sHeight,colorArray,null, Shader.TileMode.MIRROR);
  paint.setAntiAlias(true);
  paint.setStyle(Paint.Style.FILL);
  //设置渲染器
  paint.setShader(linearGradient);
  canvas.drawRoundRect(rectBlackBg, sWidth/2, 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, y, mRadius, 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.YELLOW, Color.BLUE, 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, middleColor, endColor};
 private float x,y;
 private float mRadius;
 private float progress;
 private float maxCount = 100f;
 private float sLeft, sTop, sRight, 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, sTop, sRight, sBottom);
  linearGradient=new LinearGradient(sLeft,sTop,sWidth,sHeight,colorArray,null, Shader.TileMode.MIRROR);
  paint.setAntiAlias(true);
  paint.setStyle(Paint.Style.FILL);
  //设置渲染器
  paint.setShader(linearGradient);
  canvas.drawRoundRect(rectBlackBg, sWidth/2, sWidth/2, 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, y, mRadius, thumbPaint);
  thumbPaint.setStyle(Paint.Style.STROKE);
  thumbPaint.setColor(thumbBorderColor);
  thumbPaint.setStrokeWidth(2);
  canvas.drawCircle(x, y, mRadius, 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;
 }

 public void setProgress(float progress) {
  this.progress = progress;
  invalidate();
 }
}

结束

到这里就真的结束啦,就当记录一下吧,然后也希望帮到有需要的人。有更好的实现也可以告诉我哈~

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索android
, 进度条
seekbar
seekbar进度条颜色、seekbar进度条高度、seekbar 双向进度条、seekbar 进度条宽度、seekbar 进度条 渐变,以便于您获取更多的相关知识。

时间: 2024-12-20 20:03:43

Android自定义竖直方向SeekBar多色进度条_Android的相关文章

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

写在前面 因为有这样的一个场景,需要实现竖直方向的多色进度条,然后在网上也找了下,没看到符合需要的,于是自定义了一个,效果如下: 具体实现 本来想定义水平的,然后旋转一下,后来发现还不如直接定义竖直方向来的直接,就直接在竖直方向画了下. 首先讲一下思路,就是通过继承View,然后通过onDraw()方法进行绘制.具体绘制的时候,需要处理一些小细节. 比如,我们需要画一个圆形的滑动块,那么我们的背景色带就不能把整个宽度占满,要不然,小圆块只能和色带一样宽了,效果不是很好看,所以在绘制的时候应该把背

Android 自定义view和属性动画实现充电进度条效果_Android

近期项目中需要使用到一种类似手机电池充电进度的动画效果,以前没学属性动画的时候,是用图片+定时器的方式来完成的,最近一直在学习动画这一块,再加上复习一下自定义view的相关知识点,所以打算用属性动画和自定义view的方式来完成这个功能,将它开源出来,供有需要的人了解一下相关的内容. 本次实现的功能类似下面的效果: 接下来便详细解析一下如何完成这个功能,了解其中的原理,这样就能举一反三,实现其他类似的动画效果了. 详细代码请看大屏幕 https://github.com/crazyandcoder

Android 自定义view和属性动画实现充电进度条效果

近期项目中需要使用到一种类似手机电池充电进度的动画效果,以前没学属性动画的时候,是用图片+定时器的方式来完成的,最近一直在学习动画这一块,再加上复习一下自定义view的相关知识点,所以打算用属性动画和自定义view的方式来完成这个功能,将它开源出来,供有需要的人了解一下相关的内容. 本次实现的功能类似下面的效果: 接下来便详细解析一下如何完成这个功能,了解其中的原理,这样就能举一反三,实现其他类似的动画效果了. 详细代码请看大屏幕 https://github.com/crazyandcoder

Android自定义View仿华为圆形加载进度条

View仿华为圆形加载进度条效果图 实现思路 可以看出该View可分为三个部分来实现 最外围的圆,该部分需要区分进度圆和底部的刻度圆,进度部分的刻度需要和底色刻度区分开来 中间显示的文字进度,需要让文字在View中居中显示 旋转的小圆点,小圆点需要模拟小球下落运动时的加速度效果,开始下落的时候慢,到最底部时最快,上来时速度再逐渐减慢 具体实现 先具体细分讲解,博客最后面给出全部源码 (1)首先为View创建自定义的xml属性 在工程的values目录下新建attrs.xml文件 <resourc

Android 自定义UI-垂直方向的SeekBar

 系统自带的SeekBar样式是水平的,如果需求一个垂直方向的效果就需要自定义了.原理很简单,即定义一个类继承于SeekBar,并在OnDraw方法里面旋转一下视图. 代码如下: [java] view plaincopy package android.widget;      import android.content.Context;   import android.graphics.Canvas;   import android.util.AttributeSet;   impor

ionic-Ionic的如何在竖直方向上拖拽滑动屏幕

问题描述 Ionic的如何在竖直方向上拖拽滑动屏幕 Ionic提供的滑块仅仅提供了左右滑动,现在我想做上下滑动,一开始应用了swiper,在index页面里可以正常使用,但是在标签对应的页面下会失效.我现在想的是去修改的源代码,但是项目引入的那份JS文件里好像只讲述了使用方法,还请各位大神给点意见. 解决方案 http://blog.csdn.net/jasondu264/article/details/19164897

Android零基础入门第51节:进度条ProgressBar

原文:Android零基础入门第51节:进度条ProgressBar    不知不觉这已经是第51期了,在前面50期我们学了Android开发中使用频率非常高的一些UI组件,当然这些组件还不足够完成所有APP的开发,还会经常用到一些诸如进度条.拖动条.搜索框.时间和日期选择器等组件,那么后面几期就来一起学习这些高级组件.     一.ProgressBar系列组件       ProgressBar也是一组重要的组件,ProgressBar本身代表了进度条组件,它还派生了两个常用的组件:Seek

安卓开发之自定义ProgressBar简单完成颜色渐变功能进度条

我们在使用电脑或者手机时,经常会遇到进度条,比如下图: 开发之自定义ProgressBar简单完成颜色渐变功能进度条-progressbar进度条"> 今天我来演示一下,如何做出简单并且漂亮的颜色渐变进度条. 首先我先新建了一个系统默认样式的进度条,代码如下: 运行后显示如下: 大家可以看出,并不是很好看,那么下面开始进行自定义进度条的编写吧! 首先为ProgressBar设置一个drawable,代码如下: 这个代码在哪呢,请回到上面新建系统默认样式进度条时,其中一个属性为  style

Android开发之模仿微信打开网页的进度条效果(高仿)_Android

一,为什么说是真正的高仿? 阐述这个问题前,先说下之前网上的,各位可以复制这段字,去百度一下  "仿微信打开网页的进度条效果" ,你会看到有很多类似的文章,不过他们有个共同点,就是实现方法都是一样的,而且,都忽略了微信加载网页时,进度条的缓慢动画效果,它不是生硬地一滑而过,而是用户体验很好,有个速度的变化,由慢到快的效果,语言难于描述,相信各位都有下载微信,可以随便打开个公众号的文章看看效果. 好了,上面说到,之前网上的方法都是都忽略了微信加载网页时,进度条的缓慢动画效果,实现代码也是