view 构造函数

一、四个构造函数

CustomView(Context context)

  • 源码注释
    Simple constructor to use when creating a view from code. 只是用代码创建view时调用
  • 参数context,不做过多解释

CustomView(Context context, AttributeSet attrs)

  • 源码注释
    Constructor that is called when inflating a view from XML. This is called when a view is being constructed from an XML file, supplying attributes that were specified in the XML file. This version uses a default style of 0, so the only attribute values applied are those in the Context’s Theme and the given AttributeSet. 用xml inflate生成view时调用,可以在xml中设置属性,在此构造函数中读取出来。
  • 参数(Context context, AttributeSet attrs)
    AttributeSet :A collection of attributes, as found associated with a tag in an XML document.在xml文件的标签中作为属性的集合。
    解释比较笼统,看一段代码就知道了

    布局文件:
            <com.example.test.CustomView
            android:layout_width="100dp"
            android:layout_height="200dp"
            app:testAttr1="520"
            app:testAttr2="helloworld" />
    
    
    java代码:
    
      public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
        int count = attrs.getAttributeCount();
        for (int i = 0; i < count; i++) {
        String attrName = attrs.getAttributeName(i);
        String attrVal = attrs.getAttributeValue(i);
        Log.e(TAG, "attrName = " + attrName + " , attrVal = " + attrVal);
    }}
    
    结果:
    attrName = layout_width, attrVal = 100.0dip
    attrName = layout_height, attrVal = 200.0dip
    attrName = app:testAttr2, attrVal = helloworld
    attrName = app:testAttr1, attrVal = 520
    

简单理解就是view属性的一个map而已。其中map里key为属性名,value为属性值。但是,相信有经验的开发者写自定义控件的时候,都不会这么取属性值,小伙伴应该都是这么干的

    自定义属性的声明文件:
     <?xml version="1.0" encoding="utf-8"?>
        <resources>
            <declare-styleable name="sttyleName">
                <attr name="attrName" format="string" />
            </declare-styleable>
        </resources>

java代码:
public class CustomView extends View {
    public CustomView(Context context, AttributeSetattrs) {
    super(context, attrs);
    TypedArray ta = context.obtainStyledAttributes(attrs, 
    R.styleable.sttyleName);
    String text = ta.getString(R.styleable.attrName);
    ta.recycle();
    }
}

咋一看,是绕了一圈,通过TypedArray去获取的view属性,可是,这个TypedArray是啥子东东,平时只是用了,估计也没多想。事实上,这样不但没有绕圈,反而是走了一个捷径。下面来做分析:
如果xlm的自定属性是这样的(属性值不是具体值,而是“reference”)

布局文件:
            <com.example.test.CustomView
            android:layout_width="@dimen/dp100"
            android:layout_height="@dimen/dp200"
            app:testAttr1="520"
            app:testAttr2="helloworld" />

再用上面那种遍历属性的方法得到结果就出乎意料了:

结果:
    attrName = layout_width, attrVal = @2131165234
    attrName = layout_height, attrVal = @2131165235
    attrName = app:testAttr1, attrVal = 520
    attrName = app:testAttr2, attrVal = helloworld

“@2131165234”、“@2131165235”傻眼了吧,还是得通过TypedArray来获得属性。但是有没有发现一个问题,在自定义声明属性中,我们多套了一层“ ”标签,其实可以直接写属性。这样来:

     <?xml version="1.0" encoding="utf-8"?>
        <resources>
                <attr name="attrName" format="string" />
        </resources>

但是,但是,但是(重要的事情说三遍),我们读取属性的java代码得这样写了:

public class CustomView extends View {
    private static final int[] mAttr = 
    {android.R.attr.attrName};
    private static final int ATTR_ANDROID_TEXT = 0;
    private static final int ATTR_TESTATTR = 1;

    public CustomView(Context context, AttributeSet attrs) {
    super(context, attrs);
    TypedArray ta = context.obtainStyledAttributes(attrs, mAttr);
    String text = ta.getString(ATTR_ANDROID_TEXT);
    ta.recycle();
    }
}

可以做个对比,是不是为了少写了个标签,多写了好多的代码,其实就是手动的把数组建出来了。这点也可以从R文件看出来:

  • 带标生成文件

    public static final class styleable { 
        public static final int[] sttyleName = { 0x7f010000, 
        0x7f010001 }; 
        public static final int Customize_attr1 = 1; 
        public static final int Customize_attr2= 2; 
       }
    
  • 不带标生成文件

    public static final class styleable {
        public static final int Customize_attr1 = 1; 
        public static final int Customize_attr2= 2; 
       }
    

    意思就是使用标签,系统会自动创建一个数组。

CustomView(Context context, AttributeSet attrs, int defStyleAttr)

  • 源码注释:
    Perform inflation from XML and apply a class-specific base style from a theme attribute. This constructor of View allows subclasses to use their own base style when they are inflating. For example, a Button class’s constructor would call this version of the super class constructor and supply R.attr.buttonStyle for defStyleAttr; this allows the theme’s button style to modify all of the base view attributes (in particular its background) as well as the Button class’s attributes.
    不会被系统主动调用,只能通过其他构造函数来显示调用。defStyleAttr就是上文在attr里定义在Theme里使用的CustomViewStyle

CustomView (Context context, AttributeSet attrs, int defStyleAttr, int defStyleResr)

  • 源码注释:
    Perform inflation from XML and apply a class-specific base style from a theme attribute or style resource. This constructor of View allows subclasses to use their own base style when they are inflating.
    该方法在SDK版本高于21时才出现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值