安卓自定义View

转载请标明出处:http://blog.csdn.NET/lmj623565791/article/details/24252901

很多的Android入门程序猿来说对于Android自定义View,可能都是比较恐惧的,但是这又是高手进阶的必经之路,所有准备在自定义View上面花一些功夫,多写一些文章。先总结下自定义View的步骤:

1、自定义View的属性

2、在View的构造方法中获得我们自定义的属性

[ 3、重写onMesure ]

4、重写onDraw

我把3用[]标出了,所以说3不一定是必须的,当然了大部分情况下还是需要重写的。

1、自定义View的属性,首先在res/values/  下建立一个attrs.xml , 在里面定义我们的属性和声明我们的整个样式。


第一步初始化:

//初试化操作
private void intiView() {circleRegion = new Region();
    circlePath = new Path();
    rectRegion = new Region();
    rectPath = new Path();
    SmallCircleRegion = new Region();
    SmallCirclePath = new Path();

    circlePain = new Paint();
    rectPain = new Paint();
    smallPain = new Paint();
}

系统帮我们测量的高度和宽度都是MATCH_PARNET,当我们设置明确的宽度和高度时,系统帮我们测量的结果就是我们设置的结果,当我们设置为WRAP_CONTENT,或者MATCH_PARENT系统帮我们测量的结果就是MATCH_PARENT的长度。

所以,当设置了WRAP_CONTENT时,我们需要自己进行测量,即重写onMesure方法”:

重写之前先了解MeasureSpec的specMode,一共三种类型:

EXACTLY:一般是设置了明确的值或者是MATCH_PARENT

AT_MOST:表示子布局限制在一个最大值内,一般为WARP_CONTENT

UNSPECIFIED:表示子布局想要多大就多大,很少使用

下面是我们重写onMeasure代码:

//得到属性
TypedArray array = context.obtainStyledAttributes(attrs,R.styleable.CirCleView);
circleRadius = array.getInteger(R.styleable.CirCleView_circleRadius, 300);
smallCircleRadius = array.getInteger(R.styleable.CirCleView_smallCircleRadius, 150);
textSize = array.getInteger(R.styleable.CirCleView_textSize, 50);
circleColor = array.getInteger(R.styleable.CirCleView_circleColor, Color.RED);
TextView = array.getString(R.styleable.CirCleView_TextView);

然后重写

onSizeChanged方法
    width = w;
    height = h;
    // ▼在屏幕中间添加一个矩形
    rectPath.addRect(w / 2 - 300, h / 2 - 300, w / 2 + 300, h / 2 + 300, Path.Direction.CW);
    // ▼将剪裁边界设置为视图大小
    Region globalRegion = new Region(-w, -h, w, h);
    // ▼ Path 添加到 Region     rectRegion.setPath(rectPath, globalRegion);

    //绘出中圆
    circlePath.addCircle(w / 2, h / 2, circleRadius, Path.Direction.CW);
    // ▼将剪裁边界设置为视图大小
    Region globalRegionCircle = new Region(-w, -h, w, h);
    // ▼ Path 添加到 Region     circleRegion.setPath(circlePath, globalRegion);

    //绘出小圆
    SmallCirclePath.addCircle(w / 2, h / 2, smallCircleRadius, Path.Direction.CW);
    // ▼将剪裁边界设置为视图大小
    Region globalRegionCircle3 = new Region(-w, -h, w, h);
    // ▼ Path 添加到 Region     SmallCircleRegion.setPath(SmallCirclePath, globalRegion);
}
重写OnDRAW方法
Path rect = rectPath;
rectPain.setColor(Color.GREEN);
// 绘制矩形
canvas.drawPath(rect, rectPain);

//绘制圆形
Path circle = circlePath;
circlePain.setColor(circleColor);
canvas.drawPath(circle, circlePain);
//绘制小圆
Path small = SmallCirclePath;
smallPain.setColor(Color.WHITE);
canvas.drawPath(small, smallPain);

smallPain.setColor(Color.BLACK);
smallPain.setTextSize(textSize);

float yuan = smallPain.measureText(TextView);

Paint.FontMetrics metrics = smallPain.getFontMetrics();

float ceil = (float) Math.ceil(metrics.descent - metrics.ascent);

canvas.drawText("圆环", width / 2 - yuan / 2, height / 2 + ceil / 2, smallPain);
触摸事件

@Override
public boolean onTouchEvent(MotionEvent event) {

    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:

            int x = (int) event.getX();
            int y = (int) event.getY();
            // ▼点击区域判断
            if (SmallCircleRegion.contains(x, y)) {
                Toast.makeText(this.getContext(), "在小圆内", Toast.LENGTH_SHORT).show();
            }else if (circleRegion.contains(x, y)) {
                Toast.makeText(this.getContext(), "在圆环内", Toast.LENGTH_SHORT).show();
            }else{
                Toast.makeText(this.getContext(), "在圆环外", Toast.LENGTH_SHORT).show();
            }
            break;
    }
    return true;
}


 


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值