您的位置:首页 > 移动开发 > Android开发

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

2014-11-03 09:17 393 查看
可以封装一些常用的有特殊需要的控件,一般是写一个自定义类继承某某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
写法就可以是
[align=left]<attr name= "drawableWidth" format ="dimension">[/align]
[align=left]    <enum name ="equal_textsize" value="-2" />[/align]
[align=left]</attr>[/align]
而listSelector那种又可以是颜色又可以是图片的,即color+reference
就可以在一个format中|并起来
[align=left]<attr name= "divider" format ="reference|color" />[/align]

注意:
当attrs文件中有多个declare-styleable时,
不能为重复name的attr重新设置format,类似于java中的变量,申明只能一次, 之后都直接使用
比如
[align=left]    <declare-styleable name ="DrawableTextView">[/align]
        <attr name ="drawableWidth" format="dimension" />
[align=left]        <attr name ="drawableHeight" format="dimension" />[/align]
[align=left]    </declare-styleable >[/align]
[align=left]
[/align]
[align=left]    <declare-styleable name ="DrawableButton">[/align]
        <attr
name ="drawableWidth" format="dimension" />
        <attr
name ="drawableHeight" format="dimension" />
[align=left]    </declare-styleable >[/align]
下面两行红色部分的同名attr就会报错"attribute XXX has already been defined "
正确用法应该是不再添加format参数,直接引用name
[align=left]    <declare-styleable name ="DrawableTextView">[/align]
[align=left]        <attr name ="drawableWidth" format="dimension" />[/align]
[align=left]        <attr name ="drawableHeight" format="dimension" />[/align]
[align=left]    </declare-styleable >[/align]
[align=left]
[/align]
[align=left]    <declare-styleable name ="DrawableButton">[/align]
        <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);
[align=left]
[/align]
            TypedArray
ta = context.obtainStyledAttributes(attrs,
    
                   R.styleable. DrawableTextView);
[align=left]             // dosomething[/align]
[align=left]            ta.recycle();[/align]
[align=left]      }[/align]
[align=left]
[/align]
      public DrawableTextView(Context
context, AttributeSet attrs) {
             this(context,
attrs, 0);
[align=left]      }[/align]
[align=left]
[/align]
      public DrawableTextView(Context
context) {
[align=left]             this(context, null);[/align]
[align=left]      }[/align]
[align=left]}[/align]

[align=left]然后就可以在布局中使用控件了[/align]

[align=left]< LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android"[/align]
[align=left]    xmlns:tools= "http://schemas.android.com/tools"[/align]
    xmlns:app=
"http://schemas.android.com/apk/res/com.boredream.view"
[align=left]    android:layout_width= "match_parent"[/align]
[align=left]    android:layout_height= "match_parent"[/align]
[align=left]    android:orientation= "vertical"[/align]
[align=left]    tools:context= ".MainActivity" >[/align]
[align=left]
[/align]
[align=left]    <com.boredream.view.DrawableTextView[/align]
[align=left]        android:layout_width= "wrap_content"[/align]
[align=left]        android:layout_height= "wrap_content"[/align]
[align=left]        android:drawableRight= "@drawable/ic_launcher"[/align]
[align=left]        android:text= "@string/hello_world"[/align]
[align=left]        android:textSize= "150sp"[/align]
        app:drawableHeight=
"100dp"
    
   app:drawableWidth= "100dp" />
[align=left]
[/align]
[align=left]</ LinearLayout>[/align]

[align=left]红色部分,上面的是命名空间,xmlns:后面的可以随便取,""里的内容前面固定,最后一个/后为自定义控件所在包全名[/align]
[align=left]比如我的自定义控件就是放在com.boredream.view包下的[/align]
[align=left]
[/align]
[align=left]下面则是控件使用参数方法,调用格式如下[/align]
[align=left]命名空间名:自定义参数名[/align]
[align=left]app:drawableHeight[/align]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息