安卓自定义View

来源:互联网 发布:c语言 逗号分隔符 编辑:程序博客网 时间:2024/05/17 06:41

转载请标明出处: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);
触摸事件
@Overridepublic 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;}


0 0
原创粉丝点击