安卓自定义圆环进度条的显示

效果如上图所示

关键点:

1.需要解决的问题是 自定义view的 适配问题 在不同的 手机上 显示出来的效果一致

2.所需要的 工具类  一个转换工具 px与dp之间的互转

package com.shenlei.servicemoneynew.util;

import android.content.Context;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.WindowManager;

/**
 * dpsp 转换为 px 的工具类
 *
 * @author fxsky 2012.11.12
 *
 */
public class DisplayUtil {
    /**
     * px值转换为dipdp值,保证尺寸大小不变
     *
     * @param pxValue
     * @return
     */
    public static int px2dip(Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }

    /**
     * dipdp值转换为px值,保证尺寸大小不变
     *
     * @param dipValue
     * @return
     */
    public static int dip2px(Context context, float dipValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    }

    /**
     * dipdp值转换为px值,保证尺寸大小不变
     *
     * @param dipValue
     * @return
     */
    public static float dip2pxFolat(Context context, float dipValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return  dipValue * scale + 0.5f;
    }

    /**
     * px值转换为sp值,保证文字大小不变
     *
     * @param pxValue
     * @return
     */
    public static int px2sp(Context context, float pxValue) {
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (pxValue / fontScale + 0.5f);
    }

    /**
     * sp值转换为px值,保证文字大小不变
     *
     * @param spValue
     * @return
     */
    public static int sp2px(Context context, float spValue) {
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (spValue * fontScale + 0.5f);
    }

    /**
     *
     *获取系数
     * @return
     */
    public static double getCoefficient(Context context) {
        double d = 1;
        DisplayMetrics dm = new DisplayMetrics();
        WindowManager windowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
        windowManager.getDefaultDisplay().getMetrics(dm);
        double diagonalPixels = Math.sqrt(Math.pow(dm.widthPixels, 2) + Math.pow(dm.heightPixels, 2));
        double screenInches = diagonalPixels / (160 * dm.density);
        Log.d("wh", "Screen Size : " + diagonalPixels / (160 * dm.density));
        if (screenInches >= 6.0) {
          d = screenInches/5.0;
        }
        return d;
    }

}

3.自定义的圆环类的 代码如下所示:

package com.shenlei.servicemoneynew.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;

import com.shenlei.servicemoneynew.R;
import com.shenlei.servicemoneynew.app.App;
import com.shenlei.servicemoneynew.util.DisplayUtil;

/**
 * Created by CY on 2018/3/26.
 * 自定义的圆形的view
 * 1.自定义的方法
 */

public class MyCircleView extends View {

    //画笔
    private Paint mPaint;
    private Paint mPaintTwo;//外层圆环

    private Paint mPaintText;//写文字的画笔
    private Paint mPaintTextTwo;//写百分比的画笔

    private double mInnerProgress;//外部圆环的进度

    //圆的半径 调用此方法 可以适配所有手机 保证不同型号手机的效果一致
    private float mRadius= DisplayUtil.dip2pxFolat(getContext(),50f);

    //圆的圆心的x坐标
    private float pointX ;

    //圆的圆心的Y坐标
    private float pointY;

    // 文本的中心x轴位置
    private int mXCenter;
    // 文本的中心y轴位置
    private int mYCenter;
    // 百分比文本的宽度
    private float mTxtWidth;
    // 描述文本的宽度
    private float mTxtWidth2;

    //控制是否可以移动的变量 true的时候可以移动
    private boolean moveable;


    public MyCircleView(Context context) {
        super(context);
    }

    public MyCircleView(Context context, AttributeSet attrs) {
        super(context, attrs);
        //构造一个paint 内层
        mPaint = new Paint();
        mPaint.setColor(getResources().getColor(R.color.targetColor1));
        mPaint.setStrokeWidth(DisplayUtil.dip2pxFolat(getContext(),10f));
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setAntiAlias(true);//设置防锯齿
        mPaint.setDither(true);//设置防抖

        //构造一个paint 外层
        mPaintTwo = new Paint();
        mPaintTwo.setColor(getResources().getColor(R.color.targetColor2));
        mPaintTwo.setStrokeWidth(DisplayUtil.dip2pxFolat(getContext(),10f));
        mPaintTwo.setStyle(Paint.Style.STROKE);
        mPaintTwo.setAntiAlias(true);//设置防锯齿
        mPaintTwo.setDither(true);//设置防抖

        mPaintText = new Paint();
        mPaintText.setAntiAlias(true);
        mPaintText.setStyle(Paint.Style.FILL);
        mPaintText.setColor(getResources().getColor(R.color.targetColor2));//设置黑色字体
        mPaintText.setTextSize(DisplayUtil.dip2pxFolat(getContext(),16f));//设置字体大小
        mPaintText.setDither(true);//设置防抖

        mPaintTextTwo = new Paint();
        mPaintTextTwo.setAntiAlias(true);
        mPaintTextTwo.setStyle(Paint.Style.FILL);
        mPaintTextTwo.setColor(getResources().getColor(R.color.targetColor2));//设置黑色字体
        mPaintTextTwo.setTextSize(DisplayUtil.dip2pxFolat(getContext(),16f));//设置字体大小
        mPaintTextTwo.setDither(true);//设置防抖

    }

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


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mXCenter = getWidth() / 2;
        mYCenter = getHeight() / 2;
        //根据圆心的坐标来绘制圆的位置的,而圆心的坐标,我们触摸屏幕的时候被我们修改了
        canvas.drawCircle(mXCenter, mYCenter, mRadius, mPaint);
        /*canvas.drawCircle(mXCenter, mYCenter, mRadius + 20, mPaintTwo);*/

        String txt2 = "已完成";
        mTxtWidth2 = mPaintText.measureText(txt2, 0, txt2.length());
        String txt1 = mInnerProgress+"%";//已完成百分比
        mTxtWidth = mPaintTextTwo.measureText(txt1, 0, txt1.length());
        canvas.drawText(txt1, mXCenter -mTxtWidth / 2, mYCenter + mTxtWidth/2, mPaintText);
        canvas.drawText(txt2, mXCenter - mTxtWidth2 / 2, mYCenter + mTxtWidth/8, mPaintTextTwo);


        if (mInnerProgress>0){

            RectF oval = new RectF(); // 用于定义的圆弧的形状和大小的界限
            oval.left = (mXCenter - DisplayUtil.dip2pxFolat(getContext(),60f));
            oval.top = (mYCenter - DisplayUtil.dip2pxFolat(getContext(),60f));
            oval.right = DisplayUtil.dip2pxFolat(getContext(),120f) + (mXCenter - DisplayUtil.dip2pxFolat(getContext(),60f));
            oval.bottom = DisplayUtil.dip2pxFolat(getContext(),120f)+ (mYCenter - DisplayUtil.dip2pxFolat(getContext(),60f));
            canvas.drawArc(oval, -90, ((float) mInnerProgress / 100) * 360, false, mPaintTwo); //
        }else if (mInnerProgress==0){

            RectF oval = new RectF(); // 用于定义的圆弧的形状和大小的界限
            oval.left = (mXCenter - DisplayUtil.dip2pxFolat(getContext(),60f));
            oval.top = (mYCenter - DisplayUtil.dip2pxFolat(getContext(),60f));
            oval.right = DisplayUtil.dip2pxFolat(getContext(),120f) + (mXCenter - DisplayUtil.dip2pxFolat(getContext(),60f));
            oval.bottom = DisplayUtil.dip2pxFolat(getContext(),120f)+ (mYCenter - DisplayUtil.dip2pxFolat(getContext(),60f));
            canvas.drawArc(oval, -90,360, false, mPaintTwo); //
        }
    }

    //要单点拖动,保证手指在圆上的时候才移动,我们需要判断触摸的位置
   /* @Override
    public boolean onTouchEvent(MotionEvent event) {
        //手指触摸的x坐标
        float touchX;

        //手指触摸的y坐标
        float touchY;

        //event.getAction()判断事件的类型
        switch (event.getAction()) {

            //按下的事件
            case MotionEvent.ACTION_DOWN:
                touchX = event.getX();
                touchY = event.getY();
                if (touchX > pointX - mRadius && touchX < pointX + mRadius && touchY > pointY - mRadius && touchY < pointY + mRadius) {
                    moveable = true;
                    Toast.makeText(getContext(), "我按下了", Toast.LENGTH_LONG).show();
                } else {
                    moveable = false;
                }
                break;

            //移动的事件
            case MotionEvent.ACTION_MOVE:
                if (moveable) {

                    //重新设置一下圆心的位置, 把我们圆心的位置(pointX,pointY)设置成
                    // 当前触摸的位置(event.getX()event.getY()
                    pointX = event.getX();
                    pointY = event.getY();

                    //去重新绘制, 会重新走onDraw()方法
                    invalidate();
                }
                break;

            //抬起的事件
            case MotionEvent.ACTION_UP:
                break;
        }
        return true;
    }*/

    public void setInnerProgress(double progress) {
        mInnerProgress = progress;
        //      invalidate();
        postInvalidate();
    }

}

4.比较重要的点 就是 在自定义的ui类 里面 ,需要将 设置的字体大小 ,距离等 将写的具体数字或者dp ,

   用工具类 转换 ,亲测有效。


猜你喜欢

转载自blog.csdn.net/weixin_37166398/article/details/80238324