Android自定义UI的简单实现

在app开发中经常会用到自定义UI以及效果,那么在安卓中自定义控件的流程是怎么样的呢,本文简单介绍了自定义控件的实现方式以及关键方法。

1.    自定义控件的类型

自定义控件可以简单的分为两类,一类是以继承自基本视图View与视图控件ViewGroup的自定义控件,此类控件默认无可视化UI,包括功能逻辑等都需要从头开始自定义,一切的视图都是继承自View,而ViewGroup则是继承自view的一个视图类容器。

另一类自定义控件则是继承自原生控件TextView,RecyclerView,RelativeLayout等,这种控件系统已经提供了可视化视图和一些功能逻辑,只需要开发者加以自定义化就可以直接使用。

2.实现自定义控件的关键方法

2.1 onMeasure 此方法用于测量控件实际宽高,在安卓中,没有具现化的控件是无法获取宽度与高度,此方法即是在控件具现化过程中测量宽高时被调用的回调,故此方法内可以获取到宽高,后将宽高保存下来作为后面绘画视图用到的坐标计算。

2.2 onDraw此方法提供控件的视图画布Canvas,开发者将想要的效果等通过画笔Paint绘制到画布中。

画布Canvas提供了各种方法,包括保存画板当前状态canvas.restore,此方法会将当前画板所绘制的东西保存下来,在这之后的绘制不会改变方法调用前的绘制UI。

画布简单介绍了之后我们来说说画笔,画布仅仅是提供一个可以用来作画的纸,而我们真正作画的是画笔paint,画笔paint带有多种属性,可以对线条属性进行设置,例如paint.setFlags(Paint.ANTI_ALIAS_FLAG);
设置线条抗锯齿属性。画笔和画布都准备好以后,我们要将上文计算好的宽与高,通过画布的绘制方法,例如canvas.drawline等,通过上文计算好的宽与高,计算出图形在以控件左上角为起点的坐标系中的4个点坐标,将画笔传入画板中,由安卓程序绘制出完整的图形。

2.3 onLayout此方法仅在vieGroup中使用,viewGroup如名称所示,为控件的容器,此方法作用为通过将view添加到viewGroup中后,在此方法中调用该view的onLayout方法以确定子view在容器中的位置。

 3.代码简单示例

public class DiyView extends View {
    private Paint paint1;
    private Paint paint2;
    private Path path;
    private RectF rectF;
    private float j;
    private float k;
    private float linewidth;

    public DiyView(Context context) {
        super(context);
        this.path = new Path();
        this.rectF = new RectF();
        this.j = 12.0F;
        this.k = 30.0F;
        this.linewidth = 7.0F;
        this.paint1 = new Paint();
        this.paint1.setStyle(Paint.Style.STROKE);
        this.paint1.setAntiAlias(true);
        float var3 = this.getResources().getDisplayMetrics().density;
        this.j = 12.0F * var3;
        this.paint1.setTextSize(16.0F * var3);
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) {
            this.setLayerType(1, (Paint) null);
        }

        this.paint2 = new Paint();
        this.paint2.setColor(0xff00ff00);
        this.paint2.setAntiAlias(true);
        this.k = 30.0F * var3;
        this.linewidth = linewidth * var3;
    }

    public DiyView(Context context, AttributeSet attrs) {
        this(context);
    }

    public DiyView(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, null);
    }


    /**
     * 大小变化时,此方法被调用
     * @param var1
     * @param var2
     * @param var3
     * @param var4
     */
    protected final void onSizeChanged(int var1, int var2, int var3, int var4) {
        super.onSizeChanged(var1, var2, var3, var4);
        float var5;
        float var6;
        float var7;
        float var8;
        //是否垂直,垂直为ture,水平false
        if (false) {
            var6 = (float) this.getWidth() * 0.165F;
            var8 = (float) this.getWidth() - var6;
            var7 = ((float) this.getHeight() - ((float) this.getWidth() - var6 - var6) * 0.618F) / 2.0F;
            var5 = (float) this.getHeight() - var7;
        } else {
            var6 = (float) this.getWidth() * 0.125F;
            var8 = (float) this.getWidth() - var6;
            var7 = ((float) this.getHeight() - ((float) this.getWidth() - var6 - var6) / 0.618F) / 2.0F;
            var5 = (float) this.getHeight() - var7;
        }

        this.path.reset();
        this.rectF.set(var6, var7, var8, var5);
        this.path.addRoundRect(this.rectF, this.j, this.j, Path.Direction.CW);
    }

    public final void onDraw(Canvas canvas) {
        //保存状态
        canvas.save();
        //裁剪矩形
        canvas.clipPath(this.path, Region.Op.DIFFERENCE);
        canvas.drawColor(0x88000000);
        //取出状态
        canvas.restore();

        //设置画笔为白色
        this.paint1.setColor(Color.WHITE);

        float var2 = this.k;
        float var3 = this.linewidth;
        this.paint1.setStrokeWidth(var3);

        //四个边角
        canvas.drawLine(this.rectF.left - var3 / 2.0F, this.rectF.top, this.rectF.left + var2, this.rectF.top, this.paint1);
        canvas.drawLine(this.rectF.left, this.rectF.top, this.rectF.left, this.rectF.top + var2, this.paint1);
        canvas.drawLine(this.rectF.right - var2, this.rectF.top, this.rectF.right + var3 / 2.0F, this.rectF.top, this.paint1);
        canvas.drawLine(this.rectF.right, this.rectF.top, this.rectF.right, this.rectF.top + var2, this.paint1);
        canvas.drawLine(this.rectF.right - var2, this.rectF.bottom, this.rectF.right + var3 / 2.0F, this.rectF.bottom, this.paint1);
        canvas.drawLine(this.rectF.right, this.rectF.bottom - var2, this.rectF.right, this.rectF.bottom, this.paint1);
        canvas.drawLine(this.rectF.left - var3 / 2.0F, this.rectF.bottom, this.rectF.left + var2, this.rectF.bottom, this.paint1);
        canvas.drawLine(this.rectF.left, this.rectF.bottom - var2, this.rectF.left, this.rectF.bottom, this.paint1);

    }
}

 示例为一个简单的扫描框自定义view。

转载于:https://www.cnblogs.com/orders/p/11418814.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值