Android鬼點子 CircleProgressView

分享一個最近在項目中用到的一個視圖,具體的效果以下圖:php

Screenshot_1488066156.png

打包贈送一個帶光暈的按鈕效果。java

可是由於時間比較緊,這兩個控件封裝的不是很好,使用的時候須要修改一些代碼中的參數(代碼中有詳細的comment,改起來仍是很方便的……)android

首先是上面的大圈圈。canvas

package top.greendami.circleprogressview;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RadialGradient;
import android.graphics.RectF;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.View;


/** * Created by zhaopy on 2017/2/23. */

public class CircleProgressView extends View {

    private String title = "規範評價";//顯示的文字
    private float progress = 0; //顯示的進度
    private int mLayoutSize = 100;//整個控件的尺寸(方形)
    public int mColor;//主要顏色
    public int mColorBackground;
    public int mColorShadow;

    private float now = 0; //當前的進度
    public CircleProgressView(Context context) {
        super(context);
    }

    public CircleProgressView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mColor = context.getResources().getColor(R.color.colorPrimary);
        mColorBackground = context.getResources().getColor(R.color.white);
        mColorShadow = context.getResources().getColor(R.color.shadow);
    }

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

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);

        mLayoutSize = Math.min(widthSpecSize,heightSpecSize);
        setMeasuredDimension(mLayoutSize, mLayoutSize);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        Shader mShader = new RadialGradient(mLayoutSize/2 , mLayoutSize/2, mLayoutSize/2,new int[]{Color.BLACK ,Color.DKGRAY , Color.GRAY ,Color.WHITE }
                ,null,
                Shader.TileMode.REPEAT);


        //畫陰影
        Paint paint3 = new Paint();
        paint3.setShader(mShader);
        canvas.drawCircle(mLayoutSize/2, mLayoutSize/2, mLayoutSize/2 * 0.99f, paint3);

        int centre = getWidth()/2; //獲取圓心的x座標
        float radius = mLayoutSize/2 * 0.95f; //圓環的半徑


        //畫白圓
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setColor(Color.WHITE);
        paint.setStyle(Paint.Style.FILL); //設置空心
        radius = mLayoutSize/2 * 0.925f; //圓環的半徑
        canvas.drawCircle(centre, centre, radius, paint); //畫出圓環


        //畫第一個扇形
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setColor(mColor);
        paint.setStyle(Paint.Style.FILL); //

        float boder = mLayoutSize/2 - radius;
        RectF rectF = new RectF(boder, boder ,
                mLayoutSize - boder,  mLayoutSize - boder);
        canvas.drawArc(rectF,-90,360 * (now / 100),true,paint);
        //畫第二個心裏圓,若是想讓線粗一點,把0.98f改小一點
        boder = boder * 1.2f;
        rectF = new RectF(boder, boder ,
                mLayoutSize - boder,  mLayoutSize - boder);
        paint.setColor(Color.WHITE);
        canvas.drawCircle(centre, centre, radius * 0.98f, paint); //畫出圓

        //畫頂頭的小球,0.05f是小球的半徑
        paint.setColor(mColor);

        float r = radius * 0.98f;
        canvas.drawCircle(r + (float)(r * Math.sin(Math.toRadians(360 * (now / 100)))) + boder,
                r + boder - (float)(r  * Math.cos(Math.toRadians(360 * (now / 100)))) ,
                radius * 0.05f , paint);

        String per = now + "%";

        //寫文字,1.1f控制百分比字的Y軸位置

        //寫百分比
        paint.measureText(per);
        paint.setColor(mColor);
        paint.setTextSize(mLayoutSize/5);//控制文字大小
        canvas.drawText(per,centre - paint.measureText(per)/2,centre - (paint.ascent()+ paint.descent()) * 1.1f ,paint);

        //寫標題
        paint.setColor(Color.GRAY);
        paint.setTextSize(mLayoutSize/10);//控制文字大小
        canvas.drawText(title,centre - paint.measureText(title)/2,centre + (paint.ascent()+ paint.descent()) ,paint);

        if(now < progress - 1){
            now = now + 1 ;
            postInvalidate();
        }else if(now < progress){
            now = progress;
            postInvalidate();
        }
    }

    //外部回掉
   public void setProgress(float progress,boolean isAnim) {
        this.progress = progress;
        if(!isAnim){
            now = progress;
        }
        postInvalidate();
    }
}

複製代碼

下面是按鈕的drawable,這個按鈕就是用一個drawable實現的,而後看成按鈕的背景,實現的思路是畫幾個連續的圓形廣韻,而後給按鈕的主體背景(圓角矩形)加上padding。less

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <!--畫出背景的光暈 -->

    <item android:left="65dp">
        <shape android:shape="rectangle" >
            <gradient android:endColor="#00fffaf0" android:startColor="#8049c29d" android:type="radial" android:gradientRadius="100"/>
        </shape>
    </item>
    <item android:left="25dp">
        <shape android:shape="rectangle" >
            <gradient android:endColor="#00fffaf0" android:startColor="#8049c29d" android:type="radial" android:gradientRadius="100"/>
        </shape>
    </item>
    <item >
        <shape android:shape="rectangle" >
            <gradient android:endColor="#00fffaf0" android:startColor="#8049c29d" android:type="radial" android:gradientRadius="100"/>
        </shape>
    </item>

    <item android:right="25dp">
        <shape android:shape="rectangle" >
            <gradient android:endColor="#00fffaf0" android:startColor="#8049c29d" android:type="radial" android:gradientRadius="100"/>
        </shape>
    </item>

    <item android:right="65dp">
        <shape android:shape="rectangle" >
            <gradient android:endColor="#00fffaf0" android:startColor="#8049c29d" android:type="radial" android:gradientRadius="100"/>
        </shape>
    </item>

     <!-- 畫出按鈕-->
    <item android:bottom="10dp" android:right="10dp" android:left="10dp" android:top="10dp">
        <shape android:shape="rectangle" android:useLevel="false">
            <corners android:radius="30dp" />
            <solid android:color="@color/colorPrimary" />
        </shape>
    </item>



</layer-list>
複製代碼

使用方法,我這裏固定的按鈕的大小,若是須要調整按鈕大小的話,須要改變drawable中光暈的位置()和光暈的大小(android:gradientRadius="100")ide

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" 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" android:background="@color/white" tools:context="top.greendami.circleprogressview.MainActivity">

    <top.greendami.circleprogressview.CircleProgressView android:id="@+id/cv" android:background="@color/white" android:layout_width="400dp" android:layout_height="400dp" />


    <Button android:layout_centerHorizontal="true" android:layout_alignParentBottom="true" style="?android:attr/borderlessButtonStyle" android:textColor="@color/white" android:background="@drawable/green_button_normal" android:text="開始工做" android:layout_width="130dp" android:layout_height="65dp" />
</RelativeLayout>

複製代碼

在Activity中設置進度post

CircleProgressView CV = (CircleProgressView)findViewById(R.id.cv);

CV.setProgress(35.8f);
複製代碼
相關文章
相關標籤/搜索