关闭

自定义View实现仪表盘(账户安全)

标签: Android自定义View仪表盘
757人阅读 评论(5) 收藏 举报
分类:

转载请注明出处:http://blog.csdn.net/magic_jss/article/details/52348392
群里聊天一哥们发的一个自定义View感觉很perfection,于是就根据他发的图写了个类似的效果。一个仪表盘,描述用户的账号安全等级。希望能够帮助到需要类似效果的猿/媛们,如果存在什么问题恳请指正!

效果图:

这里写图片描述

模拟器上运行效果可能有点差,真机上就比较清晰了。

1、自定义View

废话少说,直接上码;

/**
 * Created by magic on 2016年7月28日.账户安全 仪表盘view
 */
@SuppressLint({ "DrawAllocation", "ResourceAsColor" })
public class DashBoardView extends View {

    private Context context;
    // 圆
    private Paint mPaint;
    // 弧
    private Paint mPaintArc;
    // 弧的外接矩形
    private RectF rectFArc, rectFArc2;
    // text
    private Paint mPaintText;
    // line
    private Paint mPaintLine;
    // 指针路径
    private Path path;
    // 宽、高
    private float width, height;
    private float radius, arcWidth, arcWidth2, arcStrokeWidth, pointerLength,
            lineLength;
    // 设置旋转角度
    public float degrees = 0;
    private float paddingLeft, paddingTop, paddingRight, paddingBottom;

    // 底部描述文字
    private String desc;

    public DashBoardView(Context context) {
        super(context);
        this.context = context;
        init();
    }

    public DashBoardView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        init();
    }

    public DashBoardView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        init();
    }

    private void init() {
        mPaint = new Paint();
        mPaint.setColor(context.getResources().getColor(R.color.zs));
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setAntiAlias(true);

        mPaintArc = new Paint();
        mPaintArc.setStyle(Paint.Style.STROKE);
        mPaintArc.setAntiAlias(true);

        mPaintLine = new Paint();
        mPaintLine.setColor(context.getResources().getColor(R.color.zs));
        mPaintLine.setStyle(Paint.Style.FILL);
        mPaintLine.setAntiAlias(true);

        path = new Path();

        mPaintText = new Paint();
        mPaintText.setColor(context.getResources().getColor(R.color.zs));
        mPaintText.setAntiAlias(true);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int wMode = MeasureSpec.getMode(widthMeasureSpec);
        int wSize = MeasureSpec.getSize(widthMeasureSpec);
        int hMode = MeasureSpec.getMode(heightMeasureSpec);
        int hSize = MeasureSpec.getSize(heightMeasureSpec);

        // 处理宽高为 wrap_content的情况
        if (wMode == MeasureSpec.AT_MOST && hMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(200, 200);
        } else if (wMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(200, hSize);
        } else if (hMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(wSize, 200);
        }

        // 获取padding
        paddingLeft = getPaddingLeft();
        paddingTop = getPaddingTop();
        paddingRight = getPaddingRight();
        paddingBottom = getPaddingBottom();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        this.width = w - paddingLeft - paddingRight;
        this.height = h - paddingTop - paddingBottom;// 640 850 360-360

        if (width <= height) {
            arcWidth = width / 2;
        } else {
            arcWidth = height / 2;
        }

        arcStrokeWidth = (10 / 180f) * arcWidth;
        radius = 15 / 180f * arcWidth;
        pointerLength = 110 / 180f * arcWidth;
        lineLength = 15 / 180f * arcWidth;

        mPaintArc.setStrokeWidth(arcStrokeWidth);
        arcWidth2 = arcWidth - mPaintArc.getStrokeWidth();
        mPaintLine.setStrokeWidth(2 / 180f * arcWidth);
        mPaintText.setTextSize(20 / 180f * arcWidth);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.translate(width / 2 + paddingLeft, height / 2 + paddingTop);
        canvas.drawCircle(0, 0, radius, mPaint);

        rectFArc = new RectF(-arcWidth, -arcWidth, arcWidth, arcWidth);
        rectFArc2 = new RectF(-arcWidth2, -arcWidth2, arcWidth2, arcWidth2);

        mPaintArc.setColor(context.getResources().getColor(R.color.mainTextBlack));
        canvas.drawArc(rectFArc, 165, 210, false, mPaintArc);
        mPaintArc.setColor(context.getResources().getColor(R.color.hs));
        canvas.drawArc(rectFArc2, 165, 70, false, mPaintArc);
        mPaintArc.setColor(context.getResources().getColor(R.color.zs));
        canvas.drawArc(rectFArc2, 235, 70, false, mPaintArc);
        mPaintArc.setColor(context.getResources().getColor(R.color.ls));
        canvas.drawArc(rectFArc2, 305, 70, false, mPaintArc);

        float startXLine = -(arcWidth2 - (1 / 2) * arcStrokeWidth);
        float stopXLine = -(arcWidth2 - (1 / 2) * arcStrokeWidth - lineLength);
        float startXText = -mPaintText.measureText("中") / 2;
        float stopXText = -(arcWidth2 - (1 / 2) * mPaintArc.getStrokeWidth() - (2.5f) * lineLength);

        canvas.drawLine(0, startXLine, 0, stopXLine, mPaintLine);
        mPaintText.setColor(context.getResources().getColor(R.color.zs));
        canvas.drawText("中", startXText, stopXText, mPaintText);

        mPaintLine.setColor(context.getResources().getColor(R.color.hs));
        for (int i = 0; i <= 2; i++) {
            canvas.rotate(-35);
            if (i == 1) {
                mPaintText.setColor(context.getResources().getColor(R.color.hs));
                canvas.drawText("低", startXText, stopXText, mPaintText);
            }
            canvas.drawLine(0, startXLine, 0, stopXLine, mPaintLine);
        }

        canvas.rotate(105);
        mPaintLine.setColor(context.getResources().getColor(R.color.ls));
        for (int i = 0; i <= 2; i++) {
            canvas.rotate(35);
            if (i == 1) {
                mPaintText.setColor(context.getResources().getColor(R.color.ls));
                canvas.drawText("高", startXText, stopXText, mPaintText);
            }
            canvas.drawLine(0, startXLine, 0, stopXLine, mPaintLine);
        }

        canvas.rotate(-105);
        mPaintText.setColor(context.getResources().getColor(R.color.mainTextBlack));
        canvas.drawText(desc, -mPaintText.measureText(desc) / 2, pointerLength,mPaintText);
        // 画笔坐标系旋转
        canvas.rotate(-105 + degrees);
        // 绘制指针
        mPaintLine.setColor(context.getResources().getColor(R.color.zs));
        path.moveTo(radius / 2, 0);
        path.lineTo(0, -pointerLength);
        path.lineTo(-radius / 2, 0);
        canvas.drawPath(path, mPaintLine);
    }

    /**
     * 设置旋转角度
     */
    public void setDegrees(float degrees) {
        this.degrees = degrees;
        invalidate();
    }

    /**
     * 获取旋转角度
     */
    public float getDegrees() {
        return this.degrees;
    }

    /**
     * 设置底部描述
     */
    public void setTextDesc(String desc){
        this.desc=desc;
        invalidate();
    }
}

直接继承View需要处理宽高为包含内容,存在padding的情况。其中,根据在某个定值的情况下动态计算中心圆半径、指针长度、环形StrokeWidth等等,代码比较简单,直接看注释就OK!

2、xml文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:magic="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <com.mars.customview.DashBoardView
        android:id="@+id/dashBoardView"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:padding="50dp" />

</LinearLayout>

未添加自定义属性,若有相关需求可自行添加。

3、Activity中使用

/**
 * Created by magic on 2016年7月28日.
 */
public class MainActivity extends Activity {

    DashBoardView dashBoardView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        dashBoardView = (DashBoardView) findViewById(R.id.dashBoardView);

        // 账户安全 仪表盘
        ObjectAnimator animator = ObjectAnimator.ofFloat(dashBoardView,"degrees", 175);
        animator.setDuration(3000);
        // 设置插值器
        animator.setInterpolator(new DecelerateInterpolator());
        animator.start();

        dashBoardView.setTextDesc("你的账户等级  高");

    }

}

整个Demo下载地址:http://download.csdn.net/detail/magic_jss/9616384

END!

5
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:50078次
    • 积分:919
    • 等级:
    • 排名:千里之外
    • 原创:38篇
    • 转载:0篇
    • 译文:0篇
    • 评论:36条
    最新评论