Android view自定义实现动态进度条

Android  自定义view实现动态进度条

效果图:

这个是看了梁肖的demo,根据他的思路自己写了一个,但是我写的这个貌似计算还是有些问题,从上面的图就可以看出来,左侧、顶部、右侧的线会有被截掉的部分,有懂得希望能给说一下,改进一下,这个过程还是有点曲折的,不过还是觉得收获挺多的。比如通动画来进行动态的展示(之前做的都是通过Handler进行更新的所以现在换一种思路觉得特别好),还有圆弧的起止角度,矩形区域的计算等!关于绘制我们可以循序渐进,比如最开始先画圆,然后再画周围的线,最后设置动画部分就可以了。不多说了,上代码了。

代码

自定义View

public class ColorProgressBar extends View{
  //下面这两行在本demo中没什么用,只是前几天看别人的代码时学到的按一定尺寸,设置其他尺寸的方式,自动忽略或者学习一下也不错
//  private int defaultStepIndicatorNum= (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,40,getResources().getDisplayMetrics());
//  int mCircleRadius=0.28f*defaultStepIndicatorNum;

  //布局的宽高
  private int mWidth;
  private int mHeight;
  //直径
  private int mDiameter=500;

  //底层圆画笔
  private Paint mPaintbg;
  //顶层圆的画笔
  private Paint mPaintft;
  //周围线的画笔
  private Paint mPaintLine;

  //外层线条的长度
  private int mLongItem=dip2px(20);
  //线条与圆的间距
  private int mDistanceItem=dip2px(10);
  //进度条的最大宽度(取底层进度条与顶层进度条宽度最大的)
  private int mProgressWidth;

  //底层圆的颜色
  private int mBackColor;
  //顶层圆的颜色
  private int mFrontColor;
  //底层圆、顶层圆的宽度
  private float mBackWidth;
  private float mFrontWidth;
  //设置进度
  private float currentvalue;
  //通过动画演示进度
  private ValueAnimator animator;
  private int curvalue;

  public ColorProgressBar(Context context) {
    this(context,null,0);
  }

  public ColorProgressBar(Context context, AttributeSet attrs) {
    this(context, attrs,0);
  }

  public ColorProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    TypedArray ta=context.obtainStyledAttributes(attrs, R.styleable.ColorProgressBar);
    mBackColor= ta.getColor(R.styleable.ColorProgressBar_back_color, Color.BLACK);
    mFrontColor=ta.getColor(R.styleable.ColorProgressBar_front_color,mBackColor);
    mBackWidth=ta.getDimension(R.styleable.ColorProgressBar_back_width,dip2px(10));
    mFrontWidth=ta.getDimension(R.styleable.ColorProgressBar_front_width,dip2px(10));
    mProgressWidth=mBackWidth>mFrontWidth?(int)mBackWidth:(int)mFrontWidth;
    //注意释放资源
    ta.recycle();
    init();
  }

  /**
   * 都是画笔初始化
   */
  private void init() {
    mPaintbg=new Paint(Paint.ANTI_ALIAS_FLAG);
    mPaintbg.setStrokeWidth(mProgressWidth);
    mPaintbg.setColor(mBackColor);
    mPaintbg.setStrokeCap(Paint.Cap.ROUND);
    mPaintbg.setStyle(Paint.Style.STROKE);

    mPaintft=new Paint(Paint.ANTI_ALIAS_FLAG);
    mPaintft.setColor(mFrontColor);
    mPaintft.setStyle(Paint.Style.STROKE);
    mPaintft.setStrokeWidth(mFrontWidth);
    mPaintft.setStrokeCap(Paint.Cap.ROUND);

    mPaintLine=new Paint(Paint.ANTI_ALIAS_FLAG);
    mPaintLine.setColor(Color.BLACK);
    mPaintLine.setStrokeWidth(5);

  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//   宽度=高度=(长指针+指针与圆盘的间距+进度条的粗细+半径)*2
    Log.e("测量数据","LongItem:"+mLongItem+"mDistanceItem:"+mDistanceItem+"mProgressWidth:"+mProgressWidth+"mDiameter:"+mDiameter/2);
    mWidth=(int)2*(mLongItem+mDistanceItem+mProgressWidth*2+mDiameter/2);
    mHeight=(int)2*(mLongItem+mDistanceItem+mProgressWidth*2+mDiameter/2);
    Log.e("自定义View","高度"+mHeight+"宽度"+mWidth);
    setMeasuredDimension(mWidth,mHeight);
  }

  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    //绘制底层圆弧,矩形的具体计算见图片
    canvas.drawArc(new RectF(mProgressWidth/2+mDistanceItem+mLongItem,mProgressWidth/2+mDistanceItem+mLongItem,mWidth-mProgressWidth/2-mDistanceItem-mLongItem,mHeight-mProgressWidth/2-mDistanceItem-mLongItem),0,360,true,mPaintbg);
//    SweepGradient gradient=new SweepGradient();
    //绘制边缘线
    canvas.save();
    canvas.rotate(144,mWidth/2,mHeight/2);
    for(int i=0;i<=30;i++){
      canvas.rotate(-9,mWidth/2,mHeight/2);
      if(i%5==0){
        canvas.drawLine(mWidth/2,5,mWidth/2,mLongItem,mPaintbg);
      }else {
        canvas.drawLine(mWidth/2,25,mWidth/2,mLongItem,mPaintLine);
      }
    }

    canvas.restore();
    //给画笔设置渐变
    SweepGradient sweepGradient=new SweepGradient(mWidth/2,mHeight/2,Color.RED,Color.YELLOW);
    mPaintft.setShader(sweepGradient);
    //绘制顶层圆弧,currentvalue在改变时呈现动态效果
    canvas.drawArc(new RectF(mProgressWidth/2+mDistanceItem+mLongItem,mProgressWidth/2+mDistanceItem+mLongItem,mWidth-mProgressWidth/2-mDistanceItem-mLongItem,mHeight-mProgressWidth/2-mDistanceItem-mLongItem),135,currentvalue,false,mPaintft);
    mPaintft.setTextSize(100);
    mPaintft.setTextAlign(Paint.Align.CENTER);
    //绘制文本
    canvas.drawText(String.format("%.0f",currentvalue),mWidth/2,mHeight/2+50,mPaintft);
    invalidate();
  }

  /**
   * 设置动画
   * @param value
   */
  public void setCurrentValue(float value){
//    currentvalue=value;
    animator=ValueAnimator.ofFloat(currentvalue,value);
    animator.setDuration(3000);
    animator.setTarget(currentvalue);
    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
      @Override
      public void onAnimationUpdate(ValueAnimator valueAnimator) {
        currentvalue= (float) valueAnimator.getAnimatedValue();
        curvalue=curvalue/10;
      }
    });
    animator.start();

  }
  private int dip2px(float dip){
    float density=getContext().getResources().getDisplayMetrics().density;
    return (int)(dip*density+0.5f);
  }
}

矩形计算

Activity调用

 @Override
  protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.colorprogressbar);
    mBtStart1= (Button) findViewById(R.id.bt1);

    bar1= (ColorProgressBar) findViewById(R.id.cp1);

    mBtStart1.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
        bar1.setCurrentValue(270);
      }
    });

  }

自定义属性

 <declare-styleable name="ColorProgressBar">
    <attr name="back_color" format="color"></attr>
    <attr name="front_color" format="color"></attr>
    <attr name="back_width" format="dimension"></attr>
    <attr name="front_width" format="dimension"></attr>
  </declare-styleable>

布局

注意:为了使用自定义属性需要添加一行代码(AS)

xmlns:app=http://schemas.android.com/apk/res-auto

布局

<LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <Button
      android:id="@+id/bt1"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="start1"/>

    <com.demo.demo.networkdemo.colorprogressbar.widget.ColorProgressBar
      android:id="@+id/cp1"
      android:layout_width="232dp"
      android:layout_height="match_parent"
      android:layout_gravity="center_horizontal"
      app:back_color="@color/colorPrimary"
      app:front_color="@color/colorAccent"
      android:background="@mipmap/ic_launcher"/>

  </LinearLayout>

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • Android自定义View实现带数字的进度条实例代码

    第一步.效果展示 图1.蓝色的进度条 图2.红色的进度条 图3.多条颜色不同的进度条 图4.多条颜色不同的进度条 第二步.自定义ProgressBar实现带数字的进度条 0.项目结构 如上图所示:library项目为自定义的带数字的进度条NumberProgressBar的具体实现,demo项目为示例项目以工程依赖的方式引用library项目,然后使用自定义的带数字的进度条NumberProgressBar来做展示 如上图所示:自定义的带数字的进度条的library项目的结构图 如上图所示:de

  • android ListView和ProgressBar(进度条控件)的使用方法

    ListView控件的使用:ListView控件里面装的是一行一行的数据,一行中可能有多列,选中一行,则该行的几列都被选中,同时可以触发一个事件,这种控件在平时还是用得很多的.使用ListView时主要是要设置一个适配器,适配器主要是用来放置一些数据.使用起来稍微有些复杂,这里用的是android自带的SimpleAdapter,形式如下:android.widget.SimpleAdapter.SimpleAdapter(Context context, List<? extends Map<

  • Android 自定义view实现进度条加载效果实例代码

    这个其实很简单,思路是这样的,就是拿view的宽度,除以点的点的宽度+二个点 之间的间距,就可以算出大概能画出几个点出来,然后就通过canvas画出点,再然后就是每隔多少时间把上面移动的点不断的去改变它的坐标就可以, 效果如下: 分析图: 代码如下: package com.example.dotloadview; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bit

  • Android中实现Webview顶部带进度条的方法

    写这篇文章,做份备忘,简单滴展示一个带进度条的Webview示例,进度条位于Webview上面. 示例图如下: 主Activity代码: 复制代码 代码如下: package com.droidyue.demo.webviewprogressbar; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.View; import android.vi

  • Android 带进度条的WebView 示例代码

    前言 如果不使用系统自带的TitleBar(即Activity被设置@android:style/Theme.NoTitleBar),那就需要自己来写进度条了,这里封装了一个自定义控件和加载网页的公共Activity,方便使用. 正文 一.截图 二.自定义控件 复制代码 /** * 带进度条的WebView * http://www.cnblogs.com/over140/archive/2013/03/07/2947721.html * */ @SuppressWarnings("deprec

  • Android Webview添加网页加载进度条实例详解

    推荐阅读:Android WebView线性进度条实例详解 最近在android项目中使用webview嵌套了一个抽奖活动网页,活动上线,运行良好(改了N次需求和突发bug),还好这种模式的活动,只需要修改网页,不需要重新打包发布市场,这也是这种模式开发的优势之一.后来据产品哥反馈说加载网页无进度提示,好吧,这个当时真没考虑这么多,这个要加加..想当然以为轻松搞定之....其实还是比轻松要复杂点... 1.首先自定义一个WebView控件 /** * 带进度条的Webivew * @author

  • android自定义进度条渐变色View的实例代码

    最近在公司,项目不是很忙了,偶尔看见一个兄台在CSDN求助,帮忙要一个自定义的渐变色进度条,我当时看了一下进度条,感觉挺漂亮的,就尝试的去自定义view实现了一个,废话不说,先上图吧! 这个自定义的view,完全脱离了android自带的ProgressView,并且没使用一张图片,这样就能更好的降低程序代码上的耦合性! 下面我贴出代码  ,大概讲解一下实现思路吧! 复制代码 代码如下: package com.spring.progressview; import android.conten

  • Android view自定义实现动态进度条

    Android  自定义view实现动态进度条 效果图: 这个是看了梁肖的demo,根据他的思路自己写了一个,但是我写的这个貌似计算还是有些问题,从上面的图就可以看出来,左侧.顶部.右侧的线会有被截掉的部分,有懂得希望能给说一下,改进一下,这个过程还是有点曲折的,不过还是觉得收获挺多的.比如通动画来进行动态的展示(之前做的都是通过Handler进行更新的所以现在换一种思路觉得特别好),还有圆弧的起止角度,矩形区域的计算等!关于绘制我们可以循序渐进,比如最开始先画圆,然后再画周围的线,最后设置动画

  • Android  view自定义实现动态进度条

    Android  自定义view实现动态进度条 效果图: 这个是看了梁肖的demo,根据他的思路自己写了一个,但是我写的这个貌似计算还是有些问题,从上面的图就可以看出来,左侧.顶部.右侧的线会有被截掉的部分,有懂得希望能给说一下,改进一下,这个过程还是有点曲折的,不过还是觉得收获挺多的.比如通动画来进行动态的展示(之前做的都是通过Handler进行更新的所以现在换一种思路觉得特别好),还有圆弧的起止角度,矩形区域的计算等!关于绘制我们可以循序渐进,比如最开始先画圆,然后再画周围的线,最后设置动画

  • Android自定义View实现加载进度条效果

    上一篇文章总结了下自定义View的几个步骤,如果还有不清楚的同学可以先去看看Android自定义View(一),这篇文章和大家分享一下自定义加载进度条,效果如下 下面就以水平的进度条为列进行讲解: 1.首先还是在attrs.xml文件中自定义我们需要的属性: <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="GradientP

  • Android 自定义View实现多节点进度条功能

    前言 最近项目有一个节点进度条的小需求,完成后,想分享出来希望可以帮到有需要的同学. 真机效果图 自定义View完整代码 开箱即用~,注释已经炒鸡详细了 /** * @description: 节点进度条 * @author: DMingO * @date: 2020/4/15 */ public class PointProcessBar extends View { /** * 未选中时的连线画笔 */ private Paint mLinePaint; /** * 选中时的连线画笔 */

  • Android自定义多节点进度条显示的实现代码(附源码)

    亲们里面的线段颜色和节点图标都是可以自定义的. 在没给大家分享实例代码之前,先给大家展示下效果图: main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/rl_parent" xmlns:tools="http://schemas.android.com/tools" android:layou

  • Android自定义圆环式进度条

    安卓自定义圆环式进度条,供大家参考,具体内容如下 需求是实现一个圆环式中间带有进度的进度条,自己动手实现一个 package com.djt.aienglish.widget; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rec

  • Android自定义带有圆形进度条的可长按控件功能

    这几天有在学习Jetpack中CameraX的内容,在拍摄视频的时候想着做一个自定义带有进度条的可长按控件,用来显示拍摄进度,故记录下来与大家分享!效果如下: (篇幅过长是因为有代码解析过程,可直接到最后查看完整代码) 这个控件较为简易,从效果中可以看出,控件模拟了单击拍照,长按可以录制视频的功能,中途松手或者时间到都可以停止录制 思路很简单,使用简单的画笔工具就可以完成这个控件 继承自View 定义自定义属性并获取 定义填充样式的画笔 onMeasure中测量大小,onDraw中绘制圆与扇形

  • Android自定义圆形倒计时进度条

    效果预览 源代码传送门:https://github.com/yanzhenjie/CircleTextProgressbar 实现与原理 这个文字圆形的进度条我们在很多APP中看到过,比如APP欢迎页倒计时,下载文件倒计时等. 分析下原理,可能有的同学一看到这个自定义View就慌了,这个是不是要继承View啊,是不是要绘制啊之类的,答案是:是的.但是我们也不要担心,实现这个效果实在是so easy.下面就跟我一起来看看核心分析和代码吧. 原理分析 首先我们观察上图,需要几个部分组成: 1. 外

  • Android使用Canvas绘制圆形进度条效果

    前言 Android自定义控件经常会用到Canvas绘制2D图形,在优化自己自定义控件技能之前,必须熟练掌握Canvas绘图机制.本文从以下三个方面对Canvas绘图机制进行讲解: 画布Canvas 画笔Paint 示例圆形进度条 画布Canvas 首先,来看一下Android官网对Canvas类的定义: The Canvas class holds the "draw" calls.To draw something, you need 4 basic components: A B

  • android实现音乐播放器进度条效果

    本文实例为大家分享了android实现音乐播放器进度条效果的具体代码,供大家参考,具体内容如下 效果图 依赖3个对象 MediaPlayer:实现音乐播放,暂停,缓冲. SeekBar:滑动的进度条. java.util.Timer:定时器,时时更新进度条. main.xml样式文件 <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android

随机推荐