自定义进度条动起来

效果图:

自定义进度条动起来_第1张图片
image.png

自定义进度条动起来_第2张图片
image.png

xml 布局:
···


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">


    


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

···

你可能感兴趣的:(自定义进度条动起来)