王学岗自定义控件(一)

自定义控件分为四个步骤
第一:自定义属性;
第二:获取自定义属性的值;
第三:重写onMeasure()方法;(视情况而定,本步骤不是必须的)
第四:重写onDraw()方法

自定义属性;
我们写一个MyTextView类,继承View,首先要重写构造方法;如下图
这里写图片描述
我们分析下父类的三种构造方法:

//使用java代码创建的时候调用
public MyTextView(Context context) {
        super(context);
    }
//AttributSet 是属性集合,因为xml文件会被反射成一个类,使用xml文件创建view的时候会调用该构造方法
public MyTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
//defStyle是default style的简写,当有指定样式的时候调用构造方法
public MyTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

我们分析了下三个构造方法的区别,但实际开发中我们总是希望能够调用参数较多的第三种构造方法,因为参数越多越能描述当前View的特性,以至于我们总是这么写;

    public MyTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

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

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

然后我们可以在xml文件中为自定义的view添加相应的属性,但是我们发现我们现在能添加的属性大都是父类的属性,而我们自定义自己的view就是为了定义独特的属性,那我们该如何定义自己的属性呢?
这里写图片描述

第一步:我们在values文件夹下建立attrs文件
这里写图片描述

attrs文件如下

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <!-- name 值一般和自定义的类名相同 ,也可以不一样 -->
    <declare-styleable name="myTextView">

        <!--
         属性的类型
         字符串:string
         像素:dimension
         颜色:color
         引用:reference @

        -->
        <attr name="myText" format="string" />
        <attr name="myTextSize" format="dimension" />
        <attr name="myTextColor" format="color" />
    </declare-styleable>

</resources>

第二步:在activity_xml中增加命名空间
这里介绍个小技巧;res后面跟的是当前应用的包名;可以在Mainfest中获取这里写图片描述
xmlns:myandroid=”http://schemas.android.com/apk/res/com.example.zi_ding_yi_kong_jian”
第三步:获取控件的属性

 <com.example.zi_ding_yi_kong_jian.myview.MyTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        myandroid:myText="张欣喜欢我"
        myandroid:myTextColor="#13579a"
        myandroid:myTextSize="10sp" />

然后可以在MytextView中获取所有的属性,这里介绍几种获取属性值的方法
方法一:
看下MyTextView代码:

package com.example.zi_ding_yi_kong_jian.myview;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

public class MyTextView extends View {

    public MyTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        int count=attrs.getAttributeCount();
        for(int i=0;i<count;i++){
        String myName=  attrs.getAttributeName(i);
        String myValue= attrs.getAttributeValue(i);
            Log.i("zhang_xin", myName+";"+myValue);
        }
    }

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

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

}

这是打印输出结果:
这里写图片描述
与我们定义的属性一一对应;
但是这种方法有着一个明显的缺陷;那就是无法拿到引用的属性值;
如果我们的MyTextView的myText属性这么定义
myandroid:myText=”@string/myText”
我们看下打印的结果
这里写图片描述
为了解决这种情况我们只能用下面的方法了
看我们第二种方法的代码:

package com.example.zi_ding_yi_kong_jian.myview;

import com.example.zi_ding_yi_kong_jian.R;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;

public class MyTextView extends View {

    public MyTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        TypedArray ta = context.obtainStyledAttributes(attrs,
                R.styleable.myTextView);
                //数组中的第一个值
        String myText = ta.getString(R.styleable.myTextView_myText);
        // 指定颜色的默认值,如果没有定义该属性就返回默认值
        int myTextColor = ta.getColor(R.styleable.myTextView_myTextColor,
                Color.RED);
        // sp的默认值可以使用下面的方法得到,如果是dp的默认值就是TypedValue.COMPLEX_UNIT_dip
        int defaultValue = (int) TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_SP, 12, getResources()
                        .getDisplayMetrics());
        int MyTestSize = (int) ta.getDimension(
                R.styleable.myTextView_myTextSize, defaultValue);
        Log.i("zhang_xin", "myText=" + myText + "   myTextColor=" + myTextColor
                + "  MyTestSize=" + MyTestSize);
        ta.recycle();// 要回收 Be sure to call recycle() when done with them
    }

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

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

}

大家看这句代码
TypedArray ta =
context.obtainStyledAttributes(attrs, R.styleable.myTextView);
点击R.styleable.myTextView会发现R文件如下所示代码

   public static final int[] myTextView = {
            0x7f010000, 0x7f010001, 0x7f010002
        };

数组的三个元素就是我们自定义的三个属性;
R.styleable.myTextView中的styleable是和declare-styleable标签相联系的;
我们看下打印输出结果,myandroid:myText=”@string/myText”也可以打印出内容,而不是引用的地址
这里写图片描述
好了,自定义view要分好几篇博客才可以讲完;本片博客讲的都是基础的;更深入的分析请看下面的博客

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值