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

作者:danfengw 时间:2023-09-16 00:40:38 

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);
 }
}

矩形计算

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

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>

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

来源:http://blog.csdn.net/danfengw/article/details/53691083

标签:进度条,Android,view,自定义
0
投稿

猜你喜欢

  • C#使用winform简单导出Excel的方法

    2022-06-11 06:58:49
  • 详解Struts2动态方法调用

    2022-10-18 11:19:25
  • Spring中的后置处理器BeanPostProcessor详解

    2023-02-24 00:50:03
  • JAVA基于SnakeYAML实现解析与序列化YAML

    2023-11-26 06:14:44
  • C++实现图书馆管理系统源码

    2022-05-19 14:30:02
  • C#字符串和Acsii码相互转换

    2022-09-24 00:12:07
  • Android 获取IP地址的实现方法

    2023-07-30 08:09:34
  • java对指定目录下文件读写操作介绍

    2023-01-26 11:53:17
  • C#如何自定义multipart/form-data的解析器

    2023-12-04 18:59:03
  • spring依赖注入知识点分享

    2023-11-26 15:32:32
  • java基础的详细了解第六天

    2021-11-05 16:18:49
  • 使用MyBatisPlus自动生成代码后tomcat运行报错的问题及解决方法

    2022-02-23 05:24:55
  • java中for和forEach的速度比较实例Demo

    2022-06-20 07:09:58
  • Maven的几个常用plugin

    2021-12-05 13:36:28
  • android通过google api获取天气信息示例

    2023-10-18 15:44:22
  • Java如何实现树的同构?

    2023-11-28 09:55:19
  • Springboot启动流程详细分析

    2023-11-29 00:23:10
  • C# Winform 调用系统接口操作 INI 配置文件的代码

    2023-03-04 11:49:54
  • MAC下如何设置JDK环境变量

    2023-12-20 16:05:24
  • 使用 CliWrap 让C#中的命令行交互(推荐)

    2023-04-19 01:31:51
  • asp之家 软件编程 m.aspxhome.com