android群英传笔记——重写View来实现全新的控件(弧线展示图)

来源:互联网 发布:汽车单片机有哪些 编辑:程序博客网 时间:2024/05/01 13:28

弧线展示图

如下图所示就是这次的弧线展示图:

弧线展示图

根据书中的代码增加了可自定义弧形的大小,并且可以在布局中自定义各部分的颜色和大小设置。

接下来开始介绍如何创建一个这样的自定义View。

很明显,这个自定义View其实分为三个部分,分别是中间的圆形、中间显示的文字和外圈的弧线。有了这样的思路,只要在onDraw()方法中一个个去绘制就可以了。

首先,在初始化的时候,设置好绘制三种图形的参数。圆的代码如下所示:

// 中心圆的圆心坐标mCircleXY = length/2;// 中心圆的半径mRadius = (float) (length*0.5/2);

绘制弧线,需要指定其椭圆的外接矩形,代码如下所示:

        // 绘制弧形的外接矩形属性        mArcRectF = new RectF(                (float) (length * 0.1),                (float) (length * 0.1),                (float) (length * 0.9),                (float) (length * 0.9)        );

绘制文字,只要设置好文字的起始绘制位置就可以了。

接下来,我们就可以在onDraw()方法中进行绘制了,代码如下所示:

        // 绘制中心圆        canvas.drawCircle(mCircleXY, mCircleXY, mRadius, mCirclePaint);        // 绘制弧形        canvas.drawArc(mArcRectF, 270, mSweepValue, false, mArcPaint);        // 绘制文字        // 测量字体宽度,根据字体的宽度设置在圆环中间        float textWidth = mTextPaint.measureText(mShowText);        // 通过文字的大小和长度将文字绘制在圆的正中心        canvas.drawText(mShowText, 0,mShowText.length(), mCircleXY-(textWidth/2), mCircleXY+(mShowTextSize/4), mTextPaint);

当然,如果想在布局时给这个简单的View自定义属性的话,可以通过attrs.xml文件给这个控件添加可以自定义的属性,attrs.xml中设置的属性可以根据需要添加,在java中的调用方法如下所示:

        // 将所有的attrs中的所有样式都存储到TypeArray中        TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.ArcDisplay);        // 给中心圆设置属性        mCirclePaint = new Paint();        mCirclePaint.setColor(ta.getColor(R.styleable.ArcDisplay_centerCircleColor,                ContextCompat.getColor(context,R.color.defCircleColor)));        // 给弧形设置属性        mArcPaint = new Paint();        mArcPaint.setColor(ta.getColor(R.styleable.ArcDisplay_arcColor,                ContextCompat.getColor(context,R.color.defArcColor)));        mArcPaint.setStrokeWidth(ta.getInteger(R.styleable.ArcDisplay_arcWidth, 60));        mArcPaint.setStyle(Paint.Style.STROKE);        setProgress(ta.getFloat(R.styleable.ArcDisplay_arcAngle, 10));        // 给中间文字设置属性        mTextPaint = new Paint();        mTextPaint.setColor(ta.getColor(R.styleable.ArcDisplay_centerTextColor,                ContextCompat.getColor(context,R.color.defTextColor)));        mShowTextSize = ta.getInteger(R.styleable.ArcDisplay_centerFontSize, 10);        mTextPaint.setTextSize(mShowTextSize);        ta.recycle();

当调用者不具体指定属性时,可以给它们都设置一个默认值。

设置完自定义属性后,开始设置如何通过百分比的形式让弧形显示准确的比例长度,代码如下所示:

    /**     * 给弧形设置一个角度(百分比的形式)     * @param mSweepValue 角度比例     */    public void setProgress(float mSweepValue){        if (mSweepValue != 0) {            this.mSweepValue = (float) (360.0 * (mSweepValue / 100.0));            mShowText = mSweepValue + "%";        } else {            this.mSweepValue = 25;            mShowText = 25 + "%";        }        invalidate();    }

通过以上方法就可以实现输入具体的百分比让弧形长度准确显示。

以上就是弧形展示图的实现步骤,有没有很简单。

代码

以下是完整代码:

package com.example.customarc;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.RectF;import android.support.v4.content.ContextCompat;import android.util.AttributeSet;import android.view.View;import com.example.arcdisplay.R;/** * 自定义弧线展示图 * Created by shize on 2016/8/30. */public class ArcDisplay extends View {    // 中心圆的xy轴坐标    private float mCircleXY;    // 中心圆的半径    private float mRadius;    // 中心圆的画笔    private Paint mCirclePaint;    // 弧线椭圆的画笔    private Paint mArcPaint;    // 弧线扫过的角度    private float mSweepValue;    // 中心圆的文字    private String mShowText;    // 文字的画笔    private Paint mTextPaint;    // 画布的宽    private int length;    // 文字大小尺寸    private int mShowTextSize;    public ArcDisplay(Context context) {        super(context);    }    public ArcDisplay(Context context, AttributeSet attrs) {        super(context, attrs);        initView(context, attrs);    }    public ArcDisplay(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        initView(context, attrs);    }    public void initView(Context context, AttributeSet attrs){        // 将所有的attrs中的所有样式都存储到TypeArray中        TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.ArcDisplay);        // 给中心圆设置属性        mCirclePaint = new Paint();        mCirclePaint.setColor(ta.getColor(R.styleable.ArcDisplay_centerCircleColor,                ContextCompat.getColor(context,R.color.defCircleColor)));        // 给弧形设置属性        mArcPaint = new Paint();        mArcPaint.setColor(ta.getColor(R.styleable.ArcDisplay_arcColor,                ContextCompat.getColor(context,R.color.defArcColor)));        mArcPaint.setStrokeWidth(ta.getInteger(R.styleable.ArcDisplay_arcWidth, 60));        mArcPaint.setStyle(Paint.Style.STROKE);        setProgress(ta.getFloat(R.styleable.ArcDisplay_arcAngle, 10));        // 给中间文字设置属性        mTextPaint = new Paint();        mTextPaint.setColor(ta.getColor(R.styleable.ArcDisplay_centerTextColor,                ContextCompat.getColor(context,R.color.defTextColor)));        mShowTextSize = ta.getInteger(R.styleable.ArcDisplay_centerFontSize, 10);        mTextPaint.setTextSize(mShowTextSize);        ta.recycle();    }    @Override    protected void onSizeChanged(int w,int h,int oldW,int oldH){        super.onSizeChanged(w,h,oldW,oldH);        length = w;        mCircleXY = length/2;        mRadius = (float) (length*0.5/2);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        // 弧线椭圆的外接矩形        RectF mArcRectF;        // 绘制弧形的外接矩形属性        mArcRectF = new RectF(                (float) (length * 0.1),                (float) (length * 0.1),                (float) (length * 0.9),                (float) (length * 0.9)        );        // 绘制中心圆        canvas.drawCircle(mCircleXY, mCircleXY, mRadius, mCirclePaint);        // 绘制弧形        canvas.drawArc(mArcRectF, 270, mSweepValue, false, mArcPaint);        // 绘制文字        // 测量字体宽度,根据字体的宽度设置在圆环中间        float textWidth = mTextPaint.measureText(mShowText);        // 通过文字的大小和长度将文字绘制在圆的正中心        canvas.drawText(mShowText, 0,mShowText.length(), mCircleXY-(textWidth/2), mCircleXY+(mShowTextSize/4), mTextPaint);    }    /**     * 给弧形设置一个角度(百分比的形式)     * @param mSweepValue 角度比例     */    public void setProgress(float mSweepValue){        if (mSweepValue != 0) {            this.mSweepValue = (float) (360.0 * (mSweepValue / 100.0));            mShowText = mSweepValue + "%";        } else {            this.mSweepValue = 25;            mShowText = 25 + "%";        }        invalidate();    }}

布局文件调用代码:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:custom="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.arcdisplay.MainActivity">    <com.example.customarc.ArcDisplay        android:id="@+id/arc"        android:layout_width="match_parent"        android:layout_height="400dp"        custom:arcAngle="60"        custom:arcColor="#00ff00"        custom:arcWidth="60"        custom:centerCircleColor="#00ff00"        custom:centerFontSize="70"        custom:centerTextColor="#f33" />        <TextView            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:text="@string/txt_angle"/>        <EditText            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:id="@+id/angle"            android:inputType="numberDecimal"/>        <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:id="@+id/btnYes"            android:text="@string/btn_txt_yes"/></LinearLayout>

以下是attrs.xml的代码:

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="ArcDisplay">        <attr name="centerFontSize" format="integer" />        <attr name="centerTextColor" format="color" />        <attr name="centerCircleColor" format="color" />        <attr name="arcColor" format="color" />        <attr name="arcAngle" format="float" />        <attr name="arcWidth" format="integer" />    </declare-styleable></resources>

感谢阅读,下次再见。

0 0
原创粉丝点击