Android自定义View

为什么需要自定义View

Android提供了一些原生的控件如TextView、ImageView、RelativeLayout等,但是这些原生控件有时候不能满足我们的产品设计需求,这时候就要用到自定义控件。

怎样实现自定义View

这段文字翻译自Android官方文档:要实现自定义View,您通常首先要重写一些框架调用所有View的标准方法。您不需要覆盖所有这些方法。实际上,您可以从重写onDraw(android.graphics.Canvas)开始。附图(图片来自Android官方文档)。
图片来自Android官方文档

步骤

  • 创建类继承原生控件
  • 重写相应的标准方法

例子

经常遇到这样的需求,ImageView要显示圆角图片。原生的ImageView不能满足我们的需求,这时候就需要自定义View了。
- 创建RoundRectImageView继承ImageView
- 重写onSizeChanged
- 重写onDraw

public class RoundRectImageView extends ImageView {
    private Path path;//路径,用来选取绘画区域
    private RectF rectF;//矩形,确定路径时用到
    private float[] cornerRadius;//存放四个角的圆角半径,确定路径时用到

    private Paint paint;//画笔,反锯齿
    private int cornerColor;//角的颜色,设置角的颜色跟背景色一样形成圆角效果

    public RoundRectImageView(Context context) {
        this(context, null);
    }

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

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

        //初始化
        path = new Path();
        rectF = new RectF();
        rectF.left = 0;
        rectF.top = 0;
        cornerRadius = new float[8];
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        cornerColor = Color.WHITE;
    }

    //重置路径
    private void resetPath() {
        path.rewind();
        path.addRoundRect(rectF, cornerRadius, Path.Direction.CW);
        path.setFillType(Path.FillType.INVERSE_EVEN_ODD);//设置成反奇偶规则
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldW, int oldH) {
        rectF.right = w;
        rectF.bottom = h;
        resetPath();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        paint.setColor(cornerColor);
        canvas.drawPath(path, paint);
    }

    /*
     * @param leftTopRadius     左上角的圆角半径
     * @param rightTopRadius    右上角的圆角半径
     * @param leftBottomRadius  左下角的圆角半径
     * @param rightBottomRadius 右下角的圆角半径
     */
    public void setCornerRadius(int leftTopRadius, int rightTopRadius, int leftBottomRadius, int rightBottomRadius) {
        cornerRadius[0] = leftTopRadius;
        cornerRadius[1] = leftTopRadius;
        cornerRadius[2] = rightTopRadius;
        cornerRadius[3] = rightTopRadius;
        cornerRadius[4] = rightBottomRadius;
        cornerRadius[5] = rightBottomRadius;
        cornerRadius[6] = leftBottomRadius;
        cornerRadius[7] = leftBottomRadius;

        resetPath();
        invalidate();
    }

    //设置圆角颜色
    public void setCornerColor(int cornerColor) {
        this.cornerColor = cornerColor;
        invalidate();
    }
}

通过setRadius(int, int, int, int)方法设置图片的四个圆角、setCornerColor(int)设置圆角的颜色,其它用法跟ImageView一样。
path.setFillType(Path.FillType.INVERSE_EVEN_ODD)解释:当我们要给一个封闭的路径内部填充颜色时,首先需要分清哪一部分是外部,哪一部分是内部。Path类有一个方法setFillType(FillType ft) :设置路径的填充类型,这定义了如何计算“内部”。我们设置成反奇偶规则的效果是:从任意位置(绘制区域内)o作一条射线, 若与该射线相交的路径边的数目为奇数,则o是路径外部,否则就是路径内部如i1、i2。附图。
这里写图片描述
原图:
原图
效果图1:roundRectImageView.setRadius(50, 50, 50, 50);
效果图1
效果图2:roundRectImageView.setRadius(50, 50, 50, 0);
效果图2

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值