android自定义View之重写View来实现全新的控件

来源:互联网 发布:手机淘宝店铺怎么开 编辑:程序博客网 时间:2024/05/01 09:59

当android系统原生的控件无法满足我们的需要求时,我们完全可以新建一个自定义的View实现需要的功能。自定义控件通常要重写它的onDraw(),onMeasure()等方法来实现绘制逻辑。下面我就以一个例子来了解如何创建一个自定义View。
实现效果如图:
这里写图片描述
项目分析:图中的自定义View分为三个部分,分别只中间的圆形,中间的文字,外圈的弧形。我们设置View的绘制长度就是屏幕的宽度。
第一步:绘制三种图像—–创建类ArcImg,继承View

package com.wjc.drawview0504;import android.app.Application;import android.content.Context;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.RectF;import android.support.v4.content.ContextCompat;import android.util.AttributeSet;import android.util.Log;import android.view.View;/** * Created by admin on 2016/5/4. */public class ArcImg extends View {    private int mWidth;    private int mHeihgt;    private Paint mCirclePaint,mArcPaint,mTextPaint;    private float mCircleXY;    private float mRadius;    private RectF mArcRectF;    private float mSweepValue=66;    private float mSweepAngle;    private String mShowText;    private float mShowTextSie;    public ArcImg(Context context, AttributeSet attrs) {        super(context, attrs);    }        //对宽高重新进行定义    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {         mWidth=MeasureSpec.getSize(widthMeasureSpec);         mHeihgt=MeasureSpec.getSize(heightMeasureSpec);        setMeasuredDimension(mWidth,mHeihgt);        initView();    }    public void initView(){ //设置圆的参数       float length=0;//自定义View的宽度        if(mWidth>mHeihgt){            length=mHeihgt;        }else{            length=mWidth;        }        mCircleXY=(float)(length/2);//圆心坐标        mRadius=mCircleXY/2;//设置圆的半径        mCirclePaint=new Paint();//画笔        mCirclePaint.setAntiAlias(true);//平滑      // mCirclePaint.setColor(getResources().getColor(android.R.color.holo_blue_bright));//过时了        mCirclePaint.setColor(ContextCompat.getColor(getContext(),android.R.color.holo_blue_bright)); //设置弧线        mArcRectF=new RectF(                (float)(length*0.1),                (float)(length*0.1),                (float)(length*0.9),                (float)(length*0.9));        mSweepAngle=(mSweepValue/100f)*360f;//扫过的角度        mArcPaint=new Paint();        mArcPaint.setAntiAlias(true);        mArcPaint.setStrokeWidth((float) (length * 0.1));        mArcPaint.setStyle(Paint.Style.STROKE);//设置文字        mShowText=setShowText();        mShowTextSie=setShowTextSize();        mTextPaint=new Paint();        mTextPaint.setTextSize(mShowTextSie);        mTextPaint.setTextAlign(Paint.Align.CENTER);    }//绘制图像    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        //绘制圆        canvas.drawCircle(mCircleXY, mCircleXY, mRadius, mCirclePaint);        //绘制弧线        /**         * mArcRectF :指定圆弧的外轮廓矩形区域。         startAngle: 圆弧起始角度,单位为度。         sweepAngle: 圆弧扫过的角度,顺时针方向,单位为度。         useCenter: 如果为True时,在绘制圆弧时将圆心包括在内,通常用来绘制扇形。         paint: 绘制圆弧的画板属性,如颜色,是否填充等。         */      canvas.drawArc(mArcRectF, 270, mSweepAngle, false, mArcPaint);        //绘制文字        canvas.drawText(mShowText,0,mShowText.length(),mCircleXY,mCircleXY,mTextPaint);    }    private float setShowTextSize(){        this.invalidate();//刷新View,在UI线程中进行        return  30;    }    private String setShowText(){        this.invalidate();        return "Android Skill";    } //设置不同弧度的状态值    public void setSweepValue(float sweepValue){        if(sweepValue!=0){            mSweepValue=sweepValue;        }else{            mSweepValue=25;        }    }}

代码中,设置圆的颜色,在 API 23 之前使用a这种写法,但API 23 建议使用ContextCompat.getColor(context,id),如b,我使用了getContext()获取context,如果哪位有更好的方法,请告知!

a. mCirclePaint.setColor(getResources().getColor(android.R.color.holo_blue_bright));//过时了b. mCirclePaint.setColor(ContextCompat.getColor(getContext(),android.R.color.holo_blue_bright));

而在绘制文字中,我看了drawText()的源代码,实在不能理解源代码坐标(x,y)意思,我认为x,y是文字的中心,你觉得呢?

canvas.drawText(mShowText,0,mShowText.length(),mCircleXY,mCircleXY,mTextPaint);

drawText()的源代码:

 /**     * Draw the text, with origin at (x,y), using the specified paint.     * The origin is interpreted based on the Align setting in the paint.     *     * @param text  The text to be drawn     * @param start The index of the first character in text to draw     * @param end   (end - 1) is the index of the last character in text to draw     * @param x     The x-coordinate of the origin of the text being drawn     * @param y     The y-coordinate of the baseline of the text being drawn     * @param paint The paint used for the text (e.g. color, size, style)     */    public void drawText(@NonNull String text, int start, int end, float x, float y,            @NonNull Paint paint) {        if ((start | end | (end - start) | (text.length() - end)) < 0) {            throw new IndexOutOfBoundsException();        }        native_drawText(mNativeCanvasWrapper, text, start, end, x, y, paint.mBidiFlags,                paint.getNativeInstance(), paint.mNativeTypeface);    }

第二步:在布局xml中引用

    <com.wjc.drawview0504.ArcImg        android:id="@+id/circle"        android:layout_width="match_parent"        android:layout_height="match_parent" />

第三步:在activity中调用,检测自定义View是否成功

        mArcImg=(ArcImg)findViewById(R.id.circle);        mArcImg.setSweepValue(70);//指定弧度比例

好了,整个流程就这样了。现在我的案例基本是来自徐宜生的《android群英传》,如果哪位也在看这本书,欢迎一起讨论,学习。

0 0
原创粉丝点击