Android自定义View

     开学了,我大四了!哈哈。这几天回学校交学费,注册,各种东西,加上学校退宿了,所以没网络就没有更新博客,今晚回来了,就继续我们的历史吧。哈哈,开始,Android之自定义View

    Android有很多组件可以给我们直接使用,比如Button,EditText,TextView等。但有时候这些组件无法满足我们的需求。所以我们要自己来定义我们的组件。一般的自定义组件分为自定义View和 ViewGroup两种。这里我们主要介绍自定义组件View。自定义View主要有:完全自定义组件和复合自定义组件。

完全自定义组件:就是整个组件都是你自己写出来的,包括怎么画,怎么显示,有什么方法以及监听方法全部都是自己定义的。

复合自定义组件:就是继承原有的组件,在原组件的基础上进行修改。

完全自定义组件的一般步骤:

1.继承View 类,并重载前三个构造方法,API 21以上有第四个构造方法。

2.重写onDraw() ,onMeasurd()onDraw() 用于画出组件的样子onMeasure() 测量组件,宽度和高度在需要测量时调用该方法,应该进行测量计算组件将需要呈现的宽度和高度。它应该尽量保持传入的规格范围内,尽管它可以选择超过它们(在这种情况下,父视图可以选择做什么,包括裁剪,滚动,抛出一个异常,或者要求onMeasure()再次尝试,或使用不同的测量规格),宽高计算完毕后,必须调用用setMeasuredDimession(int width, int height),进行设置。否则将抛出一个异常。(可以简单理解为,当我们为组件设置宽和高时为“wrap_content”,就会调用这个方法计算组件的宽和高)。

贴代码

public class MyView extends View {

    //定义当宽和高为 wrap_content  时,我们组件的宽和高
    private static  final int WIDTH=100;
    private static  final int HEIGHT=100;

    //声明画笔
    private Paint p=null;
    //声明圆心坐标
    private int Cx,Cy;
    //声明半径
    private int Radius;


    public MyView(Context context) {
        super(context);
        init();
    }

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

    public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }


    /*
    初始化各种数据
     */

    public void init(){
        //初始化画笔
        p=new Paint();
        //设置画笔颜色
        p.setColor(getResources().getColor(R.color.colorPrimary));
        //设置为抗锯齿
        p.setAntiAlias(true);
        //设置画笔宽度
        p.setStrokeWidth(10);
        //设置画笔的样式,
        // 若为 Paint.Style.FILL,是填充样式,画出来的是实心的,
        //Paint.Style.STROKE 为空心,只有边框
        //Paint.Style.FILL_AND_STROKE   实心且有边框
        p.setStyle(Paint.Style.STROKE);



    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        /*
        画圆
        参数分别是:圆心x坐标,圆心有坐标,半径,画笔
         */
        canvas.drawCircle(Cx,Cy,Radius,p);


    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        /*
        获取设置的宽度的模式 ,
        EXACTLY:表示设置了精确的值,一般当childView设置其宽、高为精确值、match_parent时,ViewGroup会将其设置为EXACTLY;
        AT_MOST:表示子布局被限制在一个最大值内,一般当childView设置其宽、高为wrap_content时,ViewGroup会将其设置为AT_MOST;
        UNSPECIFIED:表示子布局想要多大就多大,一般出现在AadapterView的item的heightMode中、ScrollView的childView的heightMode中;
         */

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec); //获取设置的高度的模式
        int sizeWidth = MeasureSpec.getSize(widthMeasureSpec); //获取设置的宽度的大小
        int sizeHeight = MeasureSpec.getSize(heightMeasureSpec); //获取设置的高度的大小


        //通过计算来获取圆心坐标和半径
        Cx=getWidth()/2+getPaddingLeft();
        Cy=getHeight()/2+getPaddingTop();

        int Rx=getWidth()/2;
        int Ry=getHeight()/2;
        Radius=Math.min(Rx,Ry);

        //调用用setMeasuredDimession(int width, int height),进行设置
        setMeasuredDimension((widthMode==MeasureSpec.EXACTLY ? sizeWidth : WIDTH),(heightMode==MeasureSpec.EXACTLY ? sizeHeight : HEIGHT));

    }

}
以上就是自定义一个圆,下面在xml(布局文件)中使用

<com.example.customview.MyView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/text"
        />
当为宽高为wrap_content 时,效果如下

当为200dp时,效果如下



好啦,亲爱的朋友们,到这里,我们就成功的自定义一个View。当然还可以自定义监听。但我现在的博文原则是简单入门即可,所以就点到为止就好,有兴趣呢可以自己在网上搜索。有很多学习资料。


好的,今天就到这,鄙人LinLitterWhite,Android入门初学者,多多指教。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值