Android学习之路------自定义控件,圆形进度条的简单实现

简单介绍

主要是通过自定义一个view类,然后通过操作canvas和paint进行效果的实现

Step 1

新建一个attr.xml,这里主要是为了自定义我们的控件属性,attr开头的语句表示控件的自定义属性,在这里为了实现圆形进度条,定义了一下属性
radius:圆的半径
roundWidth:圆环的宽度
roundColor:圆环的初始颜色
progressColor:进度条的颜色
progressTextColor:进度数字的颜色
progressTextSize:进度数字的大小

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="progress_bar_attr">
        <attr name="radius" format="float"></attr>
        <attr name="roundWidth" format="float"></attr>
        <attr name = "roundColor" format = "color"></attr>
        <attr name = "progressColor" format = "color"></attr>
        <attr name = "progressText" format = "string"></attr>
        <attr name = "progressTextColor" format = "color"></attr>
        <attr name ="progressTextSize" format = "integer"></attr>

    </declare-styleable>

</resources>

Step 2

新建一个ProgressBarView类,继承自View,通过在类中的构造方法将属性解析出来,
radius = attr.getFloat(R.styleable.progress_bar_attr_radius,50);
这里指的是如果没设置圆的半径,我们将会得到50的默认值

package com.example.myapplication;

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

/**
 * Created by Administrator on 2016/9/24 0024.
 */
public class ProgressBarView extends View {
    private String TAG="ProgressBarView";
    /*圆的半径*/
    private static float radius;
    /*圆环的宽度*/
    private static float roundWidth;
    /*圆环的本身颜色*/
    private static int roundColor;
    /*进度条的颜色*/
    private static int progressColor;
    /*进度 字符串类型*/
    private static String progressText;
    /*进度的字体大小*/
    private static int progressTextSize;
    /*进度的字体颜色*/
    private static int   progressTextColor;
    /*圆心X,Y*/
    private static float centerX,centerY;
    /*进度 数字*/
    private static int progress = 0;

    public ProgressBarView(Context context) {
        super(context);
        Log.i(TAG,"ProgressBarView one para");
    }

    public ProgressBarView(Context context, AttributeSet attrs) {
        super(context, attrs);
        Log.i(TAG,"ProgressBarView two para");
        Log.i(TAG,"ProgressBarView three para");
        TypedArray attr = context.obtainStyledAttributes(attrs,R.styleable.progress_bar_attr);//得到attr
        radius = attr.getFloat(R.styleable.progress_bar_attr_radius,50);
        roundWidth = attr.getFloat(R.styleable.progress_bar_attr_roundWidth,10);
        roundColor = attr.getColor(R.styleable.progress_bar_attr_roundColor,Color.RED);
        progressColor = attr.getColor(R.styleable.progress_bar_attr_progressColor,Color.GREEN);
        progressTextColor = attr.getColor(R.styleable.progress_bar_attr_progressTextColor,Color.BLACK);
        progressTextSize = attr.getInteger(R.styleable.progress_bar_attr_progressTextSize,20);

        attr.recycle();
    }

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



    }

    @Override
    protected void onDraw(Canvas canvas){
        Log.i(TAG,"onDraw");
        centerX = getWidth()/2;//得到视图的x中心点
        centerY = getHeight()/2;//得到视图的y中心点
        float temp = (getWidth()<=getHeight())?getWidth():getHeight();//判断宽高,以此更好在给定视图区域画圆
        if(temp/2< radius){//防止设置的半径过大
            radius = temp/2;
        }
        Paint paint = new Paint();


        paint.setColor(roundColor);
        paint.setStrokeWidth(roundWidth);//设置画笔宽度
        paint.setStyle(Paint.Style.STROKE);//设置画笔类型,描边
        paint.setAntiAlias(true);//设置抗锯齿
        canvas.drawCircle(centerX,centerY,radius,paint);//画圆环

        paint.setColor(progressColor);
        RectF rectf = new RectF(centerX-radius,centerY-radius,centerX+radius,centerY+radius);
        canvas.drawArc(rectf,270,360*progress/100,false,paint);//画圆弧

        paint.reset();//重设画笔

        paint.setColor(progressTextColor);

        paint.setTextSize(progressTextSize);
        paint.setTextAlign(Paint.Align.CENTER);//设置字体居中
        paint.setAntiAlias(true);
        progressText = String.valueOf(progress);
        float textHeight ;
        textHeight = -paint.ascent();//
        Log.i(TAG,"height = "+textHeight);
        canvas.drawText(progressText,centerX,centerY + textHeight/2,paint);//处理之后字体显示在圆环中心

    }
    public void setProgress(int progress){//设置进度
       this.progress = progress;
        postInvalidate();//异步刷新UI,线程中调用
    }
    public void stopProgress(){
        this.progress = 0;
        postInvalidate();
    }

}

Step 3

在xml中引用我们自定义的圆形进度条
首先我们自定义了一个命名空间:progressView

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

然后我们引入我们的控件
com.example.myapplication是自定义view的包名
ProgressBarView是自定义view的类名
给自定义view设置自定义的属性:命名空间:自定义属性=” ”
例如这里

progressView:roundWidth="10"

我们设置了圆环的宽度为10,progressView是我们的命名空间,在上面定义好的

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:progressView="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"

    tools:context="com.example.myapplication.MainActivity">

    <TextView
        android:id="@+id/hello"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />
    <com.example.myapplication.ProgressBarView
        android:id="@+id/progress_bar"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_below="@+id/hello"
        progressView:roundWidth="10"
        progressView:radius="50"
        />
    <Button
        android:id="@+id/control_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:text="@string/button_text"
        android:layout_alignParentBottom="true"/>
</RelativeLayout>

Step 4

在主Activity中实现效果,主要是通过开启线程 不停的增加进度就ok了

package com.example.myapplication;

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

public class MainActivity extends AppCompatActivity {
    private Button btn;
    private static com.example.myapplication.ProgressBarView progressView;
    private static int progress = 0;
    private static boolean progressStartFlag = false;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn = (Button)findViewById(R.id.control_btn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(!progressStartFlag){
                    progressStartFlag = true;
                    progress = 0;

                    Thread progressThread = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            while(progress<=100){
                                if(!progressStartFlag){
                                    progressView.stopProgress();
                                    break;
                                }

                                progressView.setProgress(progress);
                                progress += 5;
                                if(progress>100&&progress<105){
                                    progress = 100;
                                }

                                try {
                                    Thread.sleep(100);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    });
                    progressThread.start();
                    btn.setText("停止");
                }
                else{
                    progressStartFlag = false;
                    btn.setText("开始");
                    //progressThread.
                }
            }
        });
        progressView = (com.example.myapplication.ProgressBarView)findViewById(R.id.progress_bar);

    }
    /*private static Thread progressThread =new Thread(new Runnable() {
        @Override
        public void run() {
            while(progress<=100){
                if(!progressStartFlag){
                    progressView.stopProgress();
                    break;
                }

                progressView.setProgress(progress);
                progress += 5;
                if(progress>100&&progress<105){
                    progress = 100;
                }
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    });*/
}

代码下载地址

http://download.csdn.net/detail/w71451000/9639158

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值