Android--自定义控件的xml属性

本文介绍如何在Android中创建自定义属性并应用于View组件。详细解释了定义属性、处理属性值的View类以及在布局文件中使用自定义属性的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 定义一些自定义属性

    建立一个属性xml文件: values/attrs.xml, 内容如下:

   

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.   
  4.     <!-- 图片和文字之间的位置关系  使用enum声明的属性-->  
  5.     <attr name="relation">  
  6.         <enum name="icon_left" value="0" />  
  7.         <enum name="icon_right" value="1" />  
  8.         <enum name="icon_above" value="2" />  
  9.         <enum name="icon_below" value="3" />  
  10.     </attr>  
  11.   
  12.     <declare-styleable name="IconText">  
  13.         <attr name="relation" />  
  14.         <attr name="icon" format="reference" />  
  15.         <attr name="text" format="string" />  
  16.         <attr name="text_size" format="dimension" />  
  17.         <attr name="text_color" format="integer" />  
  18.         <attr name="space" format="dimension" />  
  19.     </declare-styleable>  
  20.   
  21. </resources>  
  22. <!--  
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. 属性relation有4种可选值:icon_left, icon_right, icon_above,icon_below.  
  2.   
  3. 属性icon的可选值为引用: 例如:"@/drawbable/icon".  
  4.   
  5. 属性text的可选值为string, 例如: "Hello world", 也可是string的引用"@string/hello".  
  6.   
  7. 属性text_size的可选值为尺寸大小,例如:20sp、18dip、20px等.  
  8.   
  9. 属性text_color的可选值为整数,例如:"0xfffffff", 也可以是color的引用"@color/white".  
  10.   
  11.  -->  


该文件是定义属性名和格式的地方,需要用<declare-styleable name="IconText"></declare-styleable>包围所有属性。

其中name为该属性集的名字,主要用途是标识该属性集。

在控件的构造方法中获取自定义属性集合的时候,会使用该name。

如:TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.IconText);

如果某个属性可同时传两种不同的属性,则可以用“|”分割开即可。


2. 定义一个能够处理这些属性值的view或者layout类

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package com.test_customattributeset;  
  2.   
  3. import android.content.Context;  
  4. import android.content.res.TypedArray;  
  5. import android.util.AttributeSet;  
  6. import android.util.Log;  
  7. import android.widget.ImageView;  
  8. import android.widget.LinearLayout;  
  9. import android.widget.TextView;  
  10.   
  11. public class IconTextView extends LinearLayout {  
  12.   
  13.     private final static String TAG = IconTextView.class.getSimpleName();  
  14.     private final int ICON_LEFT = 0;  
  15.     private final int ICON_RIGHT = 1;  
  16.     private final int ICON_ABOVE = 2;  
  17.     private final int ICON_BELOW = 3;  
  18.   
  19.     private TextView mTextView;  
  20.     private ImageView mImageView;  
  21.   
  22.     private int mRelation = ICON_LEFT;  
  23.     private String mText = "";  
  24.     private int mIconId;  
  25.     private float mTextSize;  
  26.     private int mSpace;  
  27.   
  28.     public IconTextView(Context context) {  
  29.         super(context);  
  30.     }  
  31.   
  32.     public IconTextView(Context context, AttributeSet attrs) {  
  33.         super(context, attrs);  
  34.         TypedArray a = context.obtainStyledAttributes(attrs,  
  35.                 R.styleable.IconText);  
  36.   
  37.         mRelation = a.getInt(R.styleable.IconText_relation, ICON_LEFT);  
  38.   
  39.         Log.d(TAG, "mRelation: " + mRelation);  
  40.   
  41.         mText = a.getString(R.styleable.IconText_text);  
  42.   
  43.         Log.d(TAG, "mText: " + mText);  
  44.   
  45.         mTextSize = a.getDimensionPixelSize(R.styleable.IconText_text_size, 12);  
  46.   
  47.         Log.d(TAG, "mTextSize: " + mTextSize);  
  48.   
  49.         mSpace = a.getDimensionPixelSize(R.styleable.IconText_space, 5);  
  50.   
  51.         Log.d(TAG, "mSpace: " + mSpace);  
  52.   
  53.         mIconId = a.getResourceId(R.styleable.IconText_icon,  
  54.                 R.drawable.ic_launcher);  
  55.   
  56.         Log.d(TAG, "mIconId: " + mIconId);  
  57.   
  58.         a.recycle();  
  59.         mTextView = new TextView(context);  
  60.         mTextView.setText(mText);  
  61.         mTextView.setTextSize(mTextSize);  
  62.   
  63.         mImageView = new ImageView(context);  
  64.         mImageView.setImageResource(mIconId);  
  65.   
  66.         int left = 0;  
  67.   
  68.         int top = 0;  
  69.   
  70.         int right = 0;  
  71.   
  72.         int bottom = 0;  
  73.   
  74.         int orientation = HORIZONTAL;  
  75.   
  76.         int textViewIndex = 0;  
  77.   
  78.         switch (mRelation) {  
  79.   
  80.         case ICON_ABOVE:  
  81.   
  82.             orientation = VERTICAL;  
  83.   
  84.             bottom = mSpace;  
  85.   
  86.             textViewIndex = 1;  
  87.   
  88.             break;  
  89.   
  90.         case ICON_BELOW:  
  91.   
  92.             orientation = VERTICAL;  
  93.   
  94.             top = mSpace;  
  95.   
  96.             break;  
  97.   
  98.         case ICON_LEFT:  
  99.   
  100.             right = mSpace;  
  101.   
  102.             textViewIndex = 1;  
  103.   
  104.             break;  
  105.   
  106.         case ICON_RIGHT:  
  107.             left = mSpace;  
  108.             break;  
  109.   
  110.         default:  
  111.             break;  
  112.         }  
  113.   
  114.         this.setOrientation(orientation);  
  115.         this.addView(mImageView);  
  116.         mImageView.setPadding(left, top, right, bottom);  
  117.         this.addView(mTextView, textViewIndex);  
  118.     }  
  119.   
  120. }  

通过obtainStyledAttributes方法获得对属性集的引用,用“a”的各种方法来获取相应的属性值。这里需要注意的是,如果使用的方法和获取值的类型不对的话,则会返回默认值。

因此,如果一个属性是带两//个及以上不用类型的属性,需要做多次判断,直到读取完毕后才能判断应该赋予何值。当然,在取完值的时候别忘了回收资源。

类IconTextView中只有两个元素,ImageView 和mTextView,通过从xml配置文件中读取属性值来决定icon和text的内容、相对位置及其它属性。


3. 在layout布局文件中使用这个自定布局及其属性

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     xmlns:icontext="http://schemas.android.com/apk/res/com.test_customattributeset"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="match_parent"  
  6.     android:paddingBottom="@dimen/activity_vertical_margin"  
  7.     android:paddingLeft="@dimen/activity_horizontal_margin"  
  8.     android:paddingRight="@dimen/activity_horizontal_margin"  
  9.     android:paddingTop="@dimen/activity_vertical_margin"  
  10.     tools:context=".MainActivity" >  
  11.   
  12.     <com.test_customattributeset.IconTextView  
  13.         android:layout_width="wrap_content"  
  14.         android:layout_height="wrap_content"  
  15.         icontext:icon="@drawable/ic_launcher"  
  16.         icontext:relation="icon_left"  
  17.         icontext:text="hi,how are you!"  
  18.         icontext:text_size="12sp" />  
  19.   
  20. </RelativeLayout>  


注意点:我们需要在这个布局文件中加入了一个新的命名空间:

xmlns:icontext=http://schemas.android.com/apk/res/com.test_customattributeset

其中“http://schemas.android.com/apk/res/”是固定的,“com.test_customattributeset”是我们工程的包名。

"icontext"可以换成其他的任何名字.

使用如下方式使用自定义的属性:

        icontext:icon="@drawable/ic_launcher"
        icontext:relation="icon_left"
        icontext:text="hi,how are you!"
        icontext:text_size="12sp" />


4. 在Activity中使用该布局

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package com.test_customattributeset;  
  2.   
  3. import android.os.Bundle;  
  4. import android.app.Activity;  
  5. import android.view.Menu;  
  6.   
  7. public class MainActivity extends Activity {  
  8.   
  9.     @Override  
  10.     protected void onCreate(Bundle savedInstanceState) {  
  11.         super.onCreate(savedInstanceState);  
  12.         setContentView(R.layout.activity_main);  
  13.     }  
  14.   
  15.     @Override  
  16.     public boolean onCreateOptionsMenu(Menu menu) {  
  17.         // Inflate the menu; this adds items to the action bar if it is present.  
  18.         getMenuInflater().inflate(R.menu.main, menu);  
  19.         return true;  
  20.     }  
  21.   
  22. }  


运行效果如下图:



附:Android自定义属性的格式详解
1. reference:参考某一资源ID。
    (1)属性定义:
            <declare-styleable name = "名称">
                   <attr name = "background" format = "reference" />
            </declare-styleable>
    (2)属性使用:
             <ImageView
                     android:layout_width = "42dip"
                     android:layout_height = "42dip"
                     android:background = "@drawable/图片ID"
                     />
2. color:颜色值。
    (1)属性定义:
            <declare-styleable name = "名称">
                   <attr name = "textColor" format = "color" />
            </declare-styleable>
    (2)属性使用:
            <TextView
                     android:layout_width = "42dip"
                     android:layout_height = "42dip"
                     android:textColor = "#00FF00"
                     />
3. boolean:布尔值。
    (1)属性定义:
            <declare-styleable name = "名称">
                   <attr name = "focusable" format = "boolean" />
            </declare-styleable>
    (2)属性使用:
            <Button
                    android:layout_width = "42dip"
                    android:layout_height = "42dip"
                    android:focusable = "true"
                    />
4. dimension:尺寸值。
    (1)属性定义:
            <declare-styleable name = "名称">
                   <attr name = "layout_width" format = "dimension" />
            </declare-styleable>
    (2)属性使用:
            <Button
                    android:layout_width = "42dip"
                    android:layout_height = "42dip"
                    />
5. float:浮点值。
    (1)属性定义:
            <declare-styleable name = "AlphaAnimation">
                   <attr name = "fromAlpha" format = "float" />
                   <attr name = "toAlpha" format = "float" />
            </declare-styleable>
    (2)属性使用:
            <alpha
                   android:fromAlpha = "1.0"
                   android:toAlpha = "0.7"
                   />
6. integer:整型值。
    (1)属性定义:
            <declare-styleable name = "AnimatedRotateDrawable">
                   <attr name = "visible" />
                   <attr name = "frameDuration" format="integer" />
                   <attr name = "framesCount" format="integer" />
                   <attr name = "pivotX" />
                   <attr name = "pivotY" />
                   <attr name = "drawable" />
            </declare-styleable>
    (2)属性使用:
            <animated-rotate
                   xmlns:android = "http://schemas.android.com/apk/res/android
                   android:drawable = "@drawable/图片ID" 
                   android:pivotX = "50%" 
                   android:pivotY = "50%" 
                   android:framesCount = "12" 
                   android:frameDuration = "100"
                   />
7. string:字符串。
    (1)属性定义:
            <declare-styleable name = "MapView">
                   <attr name = "apiKey" format = "string" />
            </declare-styleable>
    (2)属性使用:
            <com.google.android.maps.MapView
                    android:layout_width = "fill_parent"
                    android:layout_height = "fill_parent"
                    android:apiKey = "0jOkQ80oD1JL9C6HAja99uGXCRiS2CGjKO_bc_g"
                    />
8. fraction:百分数。
    (1)属性定义:
            <declare-styleable name="RotateDrawable">
                   <attr name = "visible" />
                   <attr name = "fromDegrees" format = "float" />
                   <attr name = "toDegrees" format = "float" />
                   <attr name = "pivotX" format = "fraction" />
                   <attr name = "pivotY" format = "fraction" />
                   <attr name = "drawable" />
            </declare-styleable>
    (2)属性使用:
            <rotate  xmlns:android = "http://schemas.android.com/apk/res/android"
               android:interpolator = "@anim/动画ID"
                 android:fromDegrees = "0"
               android:toDegrees = "360"
                 android:pivotX = "200%"
                 android:pivotY = "300%"
               android:duration = "5000"
                 android:repeatMode = "restart"
                 android:repeatCount = "infinite"
                   />
9. enum:枚举值。
    (1)属性定义:
            <declare-styleable name="名称">
                   <attr name="orientation">
                          <enum name="horizontal" value="0" />
                          <enum name="vertical" value="1" />
                   </attr>           
            </declare-styleable>
    (2)属性使用:
            <LinearLayout
                    xmlns:android = "http://schemas.android.com/apk/res/android"
                    android:orientation = "vertical"
                    android:layout_width = "fill_parent"
                    android:layout_height = "fill_parent"
                    >
            </LinearLayout>
10. flag:位或运算。
     (1)属性定义:
             <declare-styleable name="名称">
                    <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>        
             </declare-styleable>
     (2)属性使用:
            <activity
                   android:name = ".StyleAndThemeActivity"
                   android:label = "@string/app_name"
                   android:windowSoftInputMode = "stateUnspecified | stateUnchanged | stateHidden">
                   <intent-filter>
                          <action android:name = "android.intent.action.MAIN" />
                          <category android:name = "android.intent.category.LAUNCHER" />
                   </intent-filter>

             </activity>
     注意:
     属性定义时可以指定多种类型值。
    (1)属性定义:
            <declare-styleable name = "名称">
                   <attr name = "background" format = "reference|color" />
            </declare-styleable>
    (2)属性使用:
             <ImageView
                     android:layout_width = "42dip"
                     android:layout_height = "42dip"
                     android:background = "@drawable/图片ID|#00FF00"
                     />




   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值