自定义控件-1.基本用法

 可以封装一些常用的有特殊需要的控件,一般是写一个自定义类继承某某View/Layout

其难点在于自定义属性attribute的设置,简单的来说就是让控件可以在xml布局中使用自己定义的特殊参数

需要在values下新建一个attrs.xml文件,在其中新建一个declare-styleable标签作为属性,name=xxx
其子属性<attr>就是一个个参数,name为参数名,format为内容格式
内容格式主要分几大类型:
1.enum型,没有format属性,需要包含几个<enum>子项,例如系统的inputType就是此类型
     <attr name = "mode">
          <enum name = "left" value= "0" />
          <enum name = "right" value= "1" />
     </attr >

2.引用型,format="reference",其值就是@+id/..@drawable/..这种
     <attr name= "viewAbove" format = "reference" />

3.数值型,format="dimension",值为20dp/dip此类
     <attr name = "drawableWidth" format= "dimension" />

4.浮点型,format="float",值为1.0/0.5...
     <attr name = "behindScrollScale" format= "float" />

5.整型,format="integer",值为15/100...
     <attr name = "level" format= "integer" />

6.百分数型,format="fraction",值为50%...
     <attr name = "fromX" format= "fraction" />

7.字符串型,format="string",值为字符串
     <attr name = "title" format= "string" />

8.布尔型,format="boolean",值为true/false
     <attr name = "isSexy" format= "boolean" />

9.颜色型,format="color",值为#fff
     <attr name = "bg" format= "color" />

10.Flag或型,无format属性,包含多个<flag>子项(用法不是太清楚)
          <attr name ="windowSoftInputMode">
          <flag name ="stateUnspecified" value= "0" />
          <flag name ="stateUnchanged" value="1" />
          <flag name ="stateHidden" value="2" />
          <flag name ="stateAlwaysHidden" value= "3" />
          <flag name ="stateVisible" value="4" />
          <flag name ="stateAlwaysVisible" value= "5" />
          <flag name ="adjustUnspecified" value= "0x00" />
          <flag name ="adjustResize" value="0x10" />
          <flag name ="adjustPan" value="0x20" />
          <flag name ="adjustNothing" value="0x30" />
     </attr >
这里以系统的某属性为例,使用时格式为
android:windowSoftInputMode = "stateUnspecified | stateUnchanged | stateHidden"


一个类型可以支持多重类型,比如系统的layout_width,即enum+dimension
写法就可以是
<attr name= "drawableWidth" format ="dimension">
    <enum name ="equal_textsize" value="-2" />
</attr>
而listSelector那种又可以是颜色又可以是图片的,即color+reference
就可以在一个format中|并起来
<attr name= "divider" format ="reference|color/>


注意:
当attrs文件中有多个declare-styleable时,
不能为重复name的attr重新设置format,类似于java中的变量,申明只能一次, 之后都直接使用
比如
    <declare-styleable name ="DrawableTextView">
        <attr name ="drawableWidth" format="dimension" />
        <attr name ="drawableHeight" format="dimension" />
    </declare-styleable >

    <declare-styleable name ="DrawableButton">
        <attr name ="drawableWidth" format="dimension" />
        <attr name ="drawableHeight" format="dimension" />
    </declare-styleable >
下面两行红色部分的同名attr就会报错"attribute XXX has already been defined "
正确用法应该是不再添加format参数,直接引用name
    <declare-styleable name ="DrawableTextView">
        <attr name ="drawableWidth" format="dimension" />
        <attr name ="drawableHeight" format="dimension" />
    </declare-styleable >

    <declare-styleable name ="DrawableButton">
        <attr name ="drawableWidth" />
        <attr name ="drawableHeight" />



写好attrs后,即可在自定义控件中的构造方法中进行处理了
一般自定义类重,会有多个构造方法
View(Context context)
View(Context context, AttributeSet attrs)
View(Context context, AttributeSet attrs, int defStyle)

通常在最后一个构造方法中处理所需逻辑~
其他两个构造方法通过this+默认参数,调用最后一个构造方法
其中最核心的方法是利用context.obtainStyledAttributes方法,将控件和自定义参数绑定,记得使用完最后recycle回收之

public class DrawableTextView extends TextView {

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

            TypedArray ta = context.obtainStyledAttributes(attrs,
                        R.styleable. DrawableTextView);

             // dosomething

            ta.recycle();
      }

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

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

}



然后就可以在布局中使用控件了
< LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android"
    xmlns:tools= "http://schemas.android.com/tools"
    xmlns:app= "http://schemas.android.com/apk/res/com.boredream.view"
    android:layout_width= "match_parent"
    android:layout_height= "match_parent"
    android:orientation= "vertical"
    tools:context= ".MainActivity" >

    <com.boredream.view.DrawableTextView
        android:layout_width= "wrap_content"
        android:layout_height= "wrap_content"
        android:drawableRight= "@drawable/ic_launcher"
        android:text= "@string/hello_world"
        android:textSize= "150sp"
        app:drawableHeight= "100dp"
        app:drawableWidth= "100dp" />

</ LinearLayout>
红色部分,上面的是命名空间,xmlns:后面的可以随便取,""里的内容前面固定,最后一个/后为自定义控件所在包全名
比如我的自定义控件就是放在com.boredream.view包下的

下面则是控件使用参数方法,调用格式如下
命名空间名:自定义参数名 
app:drawableHeight




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值