初学自定义View

1.自定义View的属性

首先在res/values/  下建立一个attrs.xml , 在里面定义我们的属性和声明我们的整个样式。我们定义了字体,字体颜色,字体大小3

个属性,format是值该属性的取值类型:
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <attr name="titleText" format="string" />
    <attr name="titleTextColor" format="color" />
    <attr name="titleTextSize" format="dimension" />

    <declare-styleable name="CustomTitleView">
        <attr name="titleText" />
        <attr name="titleTextColor" />
        <attr name="titleTextSize" />
    </declare-styleable>

</resources>

2.首先在布局中申明一个自定义View
<com.example.myapplication.CircleImage
        android:id="@+id/pytcricle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
3.创建CircleImage类继承View

4.重写两个构造方法
public CircleImage(Context context) {
        super(context);
    }


    public CircleImage(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

5.重写onMeasure
@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = getMySize(100, widthMeasureSpec);
        int height = getMySize(100, heightMeasureSpec);

        if (width < height) {
            height = width;
        } else {
            width = height;
        }

        setMeasuredDimension(width, height);
    }


在onMeasure中对View尺寸进行规划,边界参数——widthMeasureSpec和heightMeasureSpec ,效率的原因以整数的方式传入。在

它们使用之前,首先要做的是使用 MeasureSpec类的静态方法getMode和getSize来译解 ,如下面的片段所示:
private int getMySize(int defaultSize, int measureSpec) {
        int mySize = defaultSize;

        int mode = MeasureSpec.getMode(measureSpec);
        int size = MeasureSpec.getSize(measureSpec);

        switch (mode) {
            case MeasureSpec.UNSPECIFIED: {//如果没有指定大小,就设置为默认大小
                mySize = defaultSize;
                //Log.e("main","un"+size);
                break;
            }
            case MeasureSpec.AT_MOST: {//如果测量模式是最大取值为size
                //我们将大小取最大值,你也可以取其他值
               // Log.e("main","at"+size);
                mySize = 100;
                break;
            }
            case MeasureSpec.EXACTLY: {//如果是固定的大小,那就不要去改变它
               // Log.e("main","ex"+size);
                mySize = size;
                break;
            }
        }
        return mySize;
    }
依据specMode的值,( MeasureSpec有3种模式分别是UNSPECIFIED, EXACTLY和AT_MOST

     .如果是AT_MOST,specSize 代表的是最大可获得的空间;
     .如果是EXACTLY,specSize 代表的是精确的尺寸;
     .如果是UNSPECIFIED,对于控件尺寸来说,没有任何参考意义。

6.重写onDraw()方法
@Override
    protected void onDraw(Canvas canvas) {
        //调用父View的onDraw函数,因为View这个类帮我们实现了一些
        // 基本的而绘制功能,比如绘制背景颜色、背景图片等
        super.onDraw(canvas);
        int r = getMeasuredWidth() / 2;//也可以是getMeasuredHeight()/2,本例中我们已经将宽高设置相等了
        //圆心的横坐标为当前的View的左边起始位置+半径
        int centerX = getLeft() + r;
        //圆心的纵坐标为当前的View的顶部起始位置+半径
        int centerY = getTop() + r;

        Paint paint = new Paint();
        paint.setColor(Color.GREEN);
        //开始绘制
        canvas.drawCircle(centerX, centerY, r, paint);




    }
最终结果
例子






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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值