··...">
美文网首页
自定义进度条动起来

自定义进度条动起来

作者: Summer_27d1 | 来源:发表于2018-08-16 15:50 被阅读0次

    效果图:

    image.png
    image.png

    xml 布局:
    ···

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:ap="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.progress.MainActivity">

    <LinearLayout
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:orientation="vertical">
        <com.example.progress.RoundProgress
            android:id="@+id/progress"
            android:layout_width="180dp"
            android:layout_height="180dp"
            android:layout_marginTop="10dp"
            ap:roundColor="@color/colorPrimaryDark"
            ap:textColor="@color/colorPrimary"
            ap:textSize="20dp"
            ap:max="100"
            ap:progress="70"
            ap:roundProgressColor="@color/colorAccent"
            />
    
    </LinearLayout>
    

    </LinearLayout>

    ···
    MainActivity 中代码
    ···

    package com.example.progress;

    import android.os.SystemClock;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;

    public class MainActivity extends AppCompatActivity {
    private RoundProgress progress;
    Runnable runnable=new Runnable() {
    @Override
    public void run() {
    progress.setMax(100);
    for (int i = 0; i <90 ; i++) {
    progress.setProgress(i+1);
    SystemClock.sleep(20);
    //强制重绘
    // progress.invalidate(); //只有主线程可以调用
    progress.postInvalidate();//主线程 分线程都可以如此调用
    }

       }
    

    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
    }
    
    private void init() {
        progress = (RoundProgress) findViewById(R.id.progress);
       //分线程 实现进度变化
        new Thread(runnable).start();
    
    }
    

    }

    ···
    自定义类 RoundProgress 继承View
    具体代码

    ···
    package com.example.progress;

    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Rect;
    import android.graphics.RectF;
    import android.util.AttributeSet;
    import android.view.View;

    /**

    • Created by shkstart on 2016/12/3 0003.

    • 自定义视图
      */
      public class RoundProgress extends View {

      //设置绘制的圆环及文本的属性---->使用自定义属性替换
      // private int roundColor = Color.GRAY;//圆环的颜色
      // private int roundProgressColor = Color.RED;//圆弧的颜色
      // private int textColor = Color.BLUE;//文本的颜色
      //
      // private int roundWidth = UIUtils.dp2px(10);//圆环的宽度
      // private int textSize = UIUtils.dp2px(20);//文本的字体大小
      //
      // private int max = 100;//圆环的最大值
      // private int progress = 60;//圆环的进度

      //使用自定义属性来初始化如下的变量
      private int roundColor;//圆环的颜色
      private int roundProgressColor ;//圆弧的颜色
      private int textColor;//文本的颜色

      private float roundWidth ;//圆环的宽度
      private float textSize ;//文本的字体大小

      private int max;//圆环的最大值
      private int progress;//圆环的进度

      private int width;//当前视图的宽度(=高度)

      private Paint paint;//画笔

      public RoundProgress(Context context) {
      this(context, null);
      }

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

      public RoundProgress(Context context, AttributeSet attrs, int defStyleAttr) {
      super(context, attrs, defStyleAttr);

       //初始化画笔
       paint = new Paint();
       paint.setAntiAlias(true);//去除毛边
      
       //获取自定义的属性
       //1.获取TypeArray的对象(调用两个参数的方法)
       TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundProgress);
      
       //2.取出所有的自定义属性
       roundColor = typedArray.getColor(R.styleable.RoundProgress_roundColor, Color.GRAY);
       roundProgressColor = typedArray.getColor(R.styleable.RoundProgress_roundProgressColor,Color.RED);
       textColor = typedArray.getColor(R.styleable.RoundProgress_textColor,Color.GREEN);
       roundWidth = typedArray.getDimension(R.styleable.RoundProgress_roundWith,UIUtils.dp2px(10));
       textSize = typedArray.getDimension(R.styleable.RoundProgress_textSize,UIUtils.dp2px(20));
       max = typedArray.getInteger(R.styleable.RoundProgress_max,100);
       progress = typedArray.getInteger(R.styleable.RoundProgress_progress,30);
      
       //3.回收处理
       typedArray.recycle();
      

      }

      public int getMax() {
      return max;
      }

      public void setMax(int max) {
      this.max = max;
      }

      public int getProgress() {
      return progress;
      }

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

      //测量:获取当前视图宽高
      @Override
      protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
      super.onMeasure(widthMeasureSpec, heightMeasureSpec);
      width = this.getMeasuredWidth();
      }

      //canvas:画布,对应着视图在布局中的范围区间。范围的左上顶点即为坐标原点
      @Override
      protected void onDraw(Canvas canvas) {
      //1.绘制圆环
      //获取圆心坐标
      int cx = width / 2;
      int cy = width / 2;
      float radius = width / 2 - roundWidth / 2;
      paint.setColor(roundColor);//设置画笔颜色
      paint.setStyle(Paint.Style.STROKE);//设置圆环的样式
      paint.setStrokeWidth(roundWidth);//设置圆环的宽度
      canvas.drawCircle(cx, cy, radius, paint);

       //2.绘制圆弧
       RectF rectF = new RectF(roundWidth / 2, roundWidth / 2, width - roundWidth / 2, width - roundWidth / 2);
       paint.setColor(roundProgressColor);//设置画笔颜色
       canvas.drawArc(rectF,0,progress * 360 / max ,false,paint);
      
       //3.绘制文本
       String text = progress * 100 / max  + "%";
       //设置paint
       paint.setColor(textColor);
       paint.setTextSize(textSize);
       paint.setStrokeWidth(0);
       Rect rect = new Rect();//创建了一个矩形,此时矩形没有具体的宽度和高度
       paint.getTextBounds(text,0,text.length(),rect);//此时的矩形的宽度和高度即为整好包裹文本的矩形的宽高
       //获取左下顶点的坐标
       int x = width / 2 - rect.width() / 2;
       int y = width / 2 + rect.height() / 2;
      
      
       canvas.drawText(text,x,y,paint);
      

      }
      }

    ···
    MyApplication类
    ···

    package com.example.progress;
    import android.app.Application;
    import android.content.Context;
    import android.os.Handler;

    /**

    • Created by shkstart on 2016/12/2 0002.
      */
      public class MyApplication extends Application {

      //在整个应用执行过程中,需要提供的变量
      public static Context context;//需要使用的上下文对象:application实例
      public static Handler handler;//需要使用的handler
      public static Thread mainThread;//提供主线程对象
      public static int mainThreadId;//提供主线程对象的id

      @Override
      public void onCreate() {
      super.onCreate();

       context = this.getApplicationContext();
       handler = new Handler();
       mainThread = Thread.currentThread();//实例化当前Application的线程即为主线程
       mainThreadId = android.os.Process.myTid();//获取当前线程的id
      
       //设置未捕获异常的处理器
      

    // CrashHandler.getInstance().init();
    //初始化ShareSDK

    }
    

    }

    ···
    UiUtils类
    ···

    package com.example.progress;

    import android.content.Context;
    import android.os.Handler;
    import android.view.View;
    import android.widget.Toast;

    /**

    • 专门提供为处理一些UI相关的问题而创建的工具类,

    • 提供资源获取的通用方法,避免每次都写重复的代码获取结果。
      */
      public class UIUtils {

      public static Context getContext(){
      return MyApplication.context;
      }

      public static Handler getHandler(){
      return MyApplication.handler;
      }

      //返回指定colorId对应的颜色值
      public static int getColor(int colorId){
      return getContext().getResources().getColor(colorId);
      }

      //加载指定viewId的视图对象,并返回
      public static View getView(int viewId){
      View view = View.inflate(getContext(), viewId, null);
      return view;
      }

      public static String[] getStringArr(int strArrId){
      String[] stringArray = getContext().getResources().getStringArray(strArrId);
      return stringArray;
      }

      //将dp转化为px
      public static int dp2px(int dp){
      //获取手机密度
      float density = getContext().getResources().getDisplayMetrics().density;
      return (int) (dp * density + 0.5);//实现四舍五入
      }

      public static int px2dp(int px){
      //获取手机密度
      float density = getContext().getResources().getDisplayMetrics().density;
      return (int) (px / density + 0.5);//实现四舍五入
      }

      //保证runnable中的操作在主线程中执行
      public static void runOnUiThread(Runnable runnable) {
      if(isInMainThread()){
      runnable.run();
      }else{
      UIUtils.getHandler().post(runnable);
      }
      }
      //判断当前线程是否是主线程
      private static boolean isInMainThread() {
      int currentThreadId = android.os.Process.myTid();
      return MyApplication.mainThreadId == currentThreadId;

      }

      public static void toast(String message,boolean isLengthLong){
      Toast.makeText(UIUtils.getContext(), message,isLengthLong? Toast.LENGTH_LONG : Toast.LENGTH_SHORT).show();
      }
      }

    ···

    相关文章

      网友评论

          本文标题:自定义进度条动起来

          本文链接:https://www.haomeiwen.com/subject/lgkobftx.html