Android 之 自定义标签 和 自定义组件 TypedArray

  1. 自定义标签

这是我的模板项目目录
  Android 之 自定义标签 和 自定义组件 TypedArray_第1张图片
既然想像 android:text  那样使用自己的标签,那么首先得有标签。
在 res/values/ 下我新建了个  mm_tag.xml (切记不可出现大写,只能是 小写字母、数字、下划线)

第一步:    自定义 标签

mm_tag.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3.     <declare-styleable name="GridItem">
  4.         <attr name="bkground" format="reference|color"/>
  5.         <attr name="text1"    format="string"/>
  6.         <attr name="text2"    format="string"/>
  7.         <attr name="image"    format="reference|integer"/>
  8.     </declare-styleable>
  9. </resources>
format 参考:
1. reference:参考某一资源ID
2. color:颜色值
3. boolean:布尔值
4. dimension:尺寸值
5. float:浮点值
6. integer:整型值
7. string:字符串
8. fraction:百分数
9. enum:枚举值
  1. //属性定义:
  2. < declare -styleable name = "名称" >
  3.     <attr name = "orientation" >
  4.         <enum name = "horizontal" value = "0" />
  5.         <enum name = "vertical" value = "1" />
  6.     </attr>
  7. </ declare -styleable>
  8. //属性使用:
  9. <LinearLayout
  10.     xmlns:android = "http://schemas.android.com/apk/res/android"
  11.     android:orientation = "vertical"
  12.     android:layout_width = "fill_parent"
  13.     android:layout_height = "fill_parent"
  14. >
  15. </LinearLayout>
10. flag:位或运算
  1. //属性定义:
  2. < declare -styleable name = "名称" >
  3.     <attr name = "windowSoftInputMode" >
  4.         <flag name = "stateUnspecified" value = "0" />
  5.         <flag name = "stateUnchanged" value = "1" />
  6.         <flag name = "stateHidden" value = "2" />
  7.     </attr>
  8. </ declare -styleable>
  9. //属性使用:
  10. <activity
  11.     android: name = ".StyleAndThemeActivity"
  12.     android:label = "@string/app_name"
  13.     android:windowSoftInputMode = "stateUnspecified | stateUnchanged | stateHidden" >
  14.     <intent-filter>
  15.         < action android: name = "android.intent.action.MAIN" />
  16.         <category android: name = "android.intent.category.LAUNCHER" />
  17.     </intent-filter>
  18. </activity>
11.注意:属性定义时可以指定多种类型值。
  1. //属性定义:
  2. < declare -styleable name = "名称" >
  3.     <attr name = "background" format = "reference|color" />
  4. </ declare -styleable>
  5. //属性使用:
  6. <ImageView
  7.     android:layout_width = "42dip"
  8.     android:layout_height = "42dip"
  9.     android: background = "@drawable/图片ID|#00FF00" />

第二步:    在自定义组件中获得标签传回的数据

比如我们在布局中使用自定义组件 GridItem:
首先 声明好 标签的命名空间
  1. xmlns:griditem = "http://schemas.android.com/apk/res/com.mm.template"
  2. //对比下 android 的命名空间:
  3. xmlns:android = "http://schemas.android.com/apk/res/android"
发现只有 res/后面的不同, com.mm.template 是我的应用程序包名,通过 上文中的 项目目录图片可以看出来,
griditem 是我随便想的一个命名空间的名字。
接下来就是使用自定义组件

  1. < com.mm.template.GridItem
  2.      griditem:image = "@drawable/mm_1"
  3.      android:padding = "5dp"
  4.      android:layout_width = "wrap_content"
  5.      android:layout_height = "wrap_content"
  6.      android:layout_weight = "1"
  7.      griditem:bkground = "@color/orange"
  8.      griditem:text1 = "Android"       griditem:text2 = "手机开发" />
其中 用到了我们的自定义标签:
  1. griditem:image = "@drawable/mm_1"
  2. griditem:bkground = "@color/orange"
  3. griditem:text1 = "Android"
  4. griditem:text2 = "手机开发"
怎么获取标签传回的数据呢呢?
在自定义组件 GridItem 的实现代码中使用如下方法即可
  1. public GridItem(Context context, AttributeSet attrs) {
  2.     super(context, attrs);
  3. /*
  4. context通过调用obtainStyledAttributes方法来获取一个TypeArray,然后由该TypeArray来对属性进行设置
    obtainStyledAttributes方法有三个,我们最常用的是有一个参数的obtainStyledAttributes(int[] attrs),其参数直接styleable中获得
    TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.MyView);
    调用结束后务必调用recycle()方法,否则这次的设定会对下次的使用造成影响  
  5. 其中,TypedArray实例是个属性的容器,context.obtainStyledAttributes()方法返回得到。AttributeSet是节点的属性集合,在本例中是<com.easymorse.textbutton.TextButton节点中的属性集合。

    这句话:

    typedArray.getDimension(R.styleable.button_textSize, 
                    15)

    将获取自定义textSize的值,如果没有,则使用默认的值,15。


    */
  6.     TypedArray typedarray=context.obtainStyledAttributes(attrs, R.styleable.GridItem);
  7.     bk_color =typedarray.getResourceId(R.styleable.GridItem_bkground, R.color.burlywood);
  8.     text1 =typedarray.getString(R.styleable.GridItem_text1);
  9.     text2 =typedarray.getString(R.styleable.GridItem_text2);
  10.     image=typedarray.getDrawable(R.styleable.GridItem_image);
  11.     typedarray.recycle();
  12.     view=LayoutInflater.from(context).inflate(R.layout.mm_grid_item, this,true);
  13.     layout=(LinearLayout)view.findViewById(R.id.item_layout);
  14.     textview1=(TextView)view.findViewById(R.id.text1);
  15.     textview2=(TextView)view.findViewById(R.id.text2);
  16.     imageview=(ImageView)view.findViewById(R.id.imageview);
  17.     layout.setBackgroundResource(bk_color); //设置背景色
  18.     textview1.setText(text1);               //设置第一行文字
  19.     textview2.setText(text2);               //设置第二行文字
  20.     imageview.setImageDrawable(image);      //设置图标
  21. }
即可获得 我们自定义标签传过来的数据,并且正确的在界面中显示出来。
下面我将结合自定义 组件 GridItem 来一起讲。

2    自定义组件

我想实现一个组件,类似于这样的
  Android 之 自定义标签 和 自定义组件 TypedArray_第2张图片
方法有很多种,自定义布局即可,现在我想让它以组件的形式在 布局中直接 像 TextView 一样使用,
Android 之 自定义标签 和 自定义组件 TypedArray_第3张图片
那么就用到自定义组件。
下面我将实现一个自定义组件 GridItem 实现。
一般都是继承于 Layout(我用继承于View时出现问题 ~~!)
GridItem.java
  1. package com.mm.template;
  2. import android.content.Context;
  3. import android.content.res.TypedArray;
  4. import android.graphics.drawable.Drawable;
  5. import android.util.AttributeSet;
  6. import android.view.LayoutInflater;
  7. import android.view.View;
  8. import android.widget.ImageView;
  9. import android.widget.LinearLayout;
  10. import android.widget.TextView;
  11. public class GridItem extends LinearLayout {
  12.     private int bk_color;   //背景色
  13.     private String text1;   //第一行文字
  14.     private String text2;   //第二行文字
  15.     private Drawable image; //图标
  16.     private LinearLayout layout;
  17.     private TextView textview1;
  18.     private TextView textview2;
  19.     private ImageView imageview;
  20.     private View view;
  21.     public GridItem(Context context, AttributeSet attrs) {
  22.         super(context, attrs);
  23.         TypedArray typedarray=context.obtainStyledAttributes(attrs, R.styleable.GridItem);
  24.         bk_color =typedarray.getResourceId(R.styleable.GridItem_bkground, R.color.burlywood);
  25.         text1 =typedarray.getString(R.styleable.GridItem_text1);
  26.         text2 =typedarray.getString(R.styleable.GridItem_text2);
  27.         image=typedarray.getDrawable(R.styleable.GridItem_image);
  28.         typedarray.recycle();
  29.         view=LayoutInflater.from(context).inflate(R.layout.mm_grid_item, this,true);
  30.         layout=(LinearLayout)view.findViewById(R.id.item_layout);
  31.         textview1=(TextView)view.findViewById(R.id.text1);
  32.         textview2=(TextView)view.findViewById(R.id.text2);
  33.         imageview=(ImageView)view.findViewById(R.id.imageview);
  34.         layout.setBackgroundResource(bk_color); //设置背景色
  35.         textview1.setText(text1);               //设置第一行文字
  36.         textview2.setText(text2);               //设置第二行文字
  37.         imageview.setImageDrawable(image);      //设置图标
  38.     }
  39. }

这个自定义组件 GridItem 用到的布局文件

mm_grid_item.xml
  1. <? xml   version = "1.0"    encoding = "utf-8" ?>
  2. < LinearLayout   xmlns:android = "http://schemas.android.com/apk/res/android"
  3.      xmlns:tools = "http://schemas.android.com/tools"
  4.      android: id = "@+id/item_layout"
  5.      android:layout_width = "match_parent"
  6.      android:layout_height = "match_parent"
  7.      android:orientation = "vertical"
  8.      android: background = "@color/black"
  9.      android:padding = "3dp"
  10.      android:paddingLeft = "6dp"
  11.      tools:ignore = "HardcodedText,ContentDescription"    >
  12.      < TextView
  13.          android: id = "@+id/text1"
  14.          android:layout_weight = "1"
  15.           style = "@style/MM_TextView" />
  16.      < TextView
  17.          android: id = "@+id/text2"
  18.          android:layout_weight = "1"
  19.          android:textSize = "12sp"
  20.           style = "@style/MM_TextView" />
  21.      < ImageView
  22.          android: id = "@+id/imageview"
  23.          android:layout_width = "wrap_content"
  24.          android:layout_height = "0dp"
  25.          android:layout_gravity = "right"
  26.          android: src = "@drawable/mm_title_1"
  27.          android:layout_weight = "2"
  28.          android:layout_marginTop = "10dp"
  29.          android:scaleType = "fitCenter" />
  30.       <!--图片缩放
  31.         android:scaleX="0.8"
  32.         android:scaleY="0.8" --> </ LinearLayout >

3    使用方法

在  main_layout.xml (我的主布局文件)中使用
  1. < LinearLayout   xmlns:android = "http://schemas.android.com/apk/res/android"
  2.      xmlns:tools = "http://schemas.android.com/tools"
  3.      xmlns:griditem = "http://schemas.android.com/apk/res/com.mm.template"
  4.      android:layout_width = "match_parent"
  5.      android:layout_height = "match_parent"
  6.      android: background = "@color/white"
  7.      android:orientation = "vertical"
  8.      tools:ignore = "HardcodedText,ContentDescription,NestedWeights"    >
  9.       <!-- Head start -->
  10.      < LinearLayout
  11.          android:layout_width = "match_parent"
  12.          android:layout_height = "44dp"
  13.          android:orientation = "horizontal"
  14.          android:padding = "10dp"
  15.          android: background = "@color/red" >
  16.          < ImageView
  17.              android:layout_width = "wrap_content"
  18.              android:layout_height = "match_parent"
  19.              android: src = "@drawable/mm_title_1"    />
  20.          < TextView
  21.              android:layout_width = "0dp"
  22.              android:layout_height = "match_parent"
  23.              android:layout_weight = "1"
  24.              android:gravity = "center"
  25.              android: text = "测试案例"
  26.              android:textStyle = "bold"
  27.              android:textSize = "16sp"
  28.              android:textColor = "@android:color/white" />
  29.          < ImageView
  30.              android:layout_width = "wrap_content"
  31.              android:layout_height = "match_parent"
  32.              android: src = "@drawable/mm_title_2"    />
  33.      </ LinearLayout >
  34.       <!-- Head end   -->
  35.       <!-- Search start-->
  36.      < LinearLayout
  37.          android:layout_width = "match_parent"
  38.          android:layout_height = "36dp"
  39.          android:orientation = "vertical"
  40.          android:paddingTop = "3dp"
  41.          android:layout_margin = "8dp" >
  42.          < EditText
  43.              android: id = "@+id/search_edit"
  44.              android:layout_width = "match_parent"
  45.              android:layout_height = "match_parent"
  46.              android:drawableLeft = "@drawable/mm_search"
  47.                android: background = "@drawable/mm_shape_editview"
  48.                android:hint = "请输入关键字"
  49.              android:textSize = "16sp"
  50.              android:textColorHint = "@color/darkgray"
  51.              android:textStyle = "bold"
  52.              android:padding = "6dp" />
  53.      </ LinearLayout >
  54.       <!-- Search end  -->
  55.       <!-- GridItem start  -->
  56.      < LinearLayout
  57.            android:layout_width = "match_parent"
  58.            android:layout_height = "0dp"
  59.            android:layout_weight = "1"
  60.            android:orientation = "horizontal"
  61.          android:layout_margin = "10dp" >
  62.          < com.mm.template.GridItem
  63.              griditem:image = "@drawable/mm_1"
  64.              android:padding = "5dp"
  65.                android:layout_width = "wrap_content"
  66.                android:layout_height = "wrap_content"
  67.                android:layout_weight = "1"
  68.                griditem:bkground = "@color/orange"
  69.                griditem:text1 = "Android"
  70.                griditem:text2 = "手机开发" />
  71.          < com.mm.template.GridItem
  72.              griditem:image = "@drawable/mm_2"
  73.              android:padding = "5dp"
  74.                android:layout_width = "wrap_content"
  75.                android:layout_height = "wrap_content"
  76.                android:layout_weight = "1"
  77.                griditem:bkground = "@color/blueviolet"
  78.                griditem:text1 = "C++"
  79.                griditem:text2 = "编程语言" />
  80.          < com.mm.template.GridItem
  81.              griditem:image = "@drawable/mm_3"
  82.              android:padding = "5dp"
  83.                android:layout_width = "wrap_content"
  84.                android:layout_height = "wrap_content"
  85.                android:layout_weight = "1"
  86.                griditem:bkground = "@color/blue"
  87.                griditem:text1 = "服务端"
  88.                griditem:text2 = "后台开发" />
  89.      </ LinearLayout >
  90.       <!-- GridItem end  --> </ LinearLayout >
也就是 <com /> 标签为我们自定义的 GridItem 组件。

4    结果展示

  Android 之 自定义标签 和 自定义组件 TypedArray_第4张图片

你可能感兴趣的:(Android 之 自定义标签 和 自定义组件 TypedArray)