一、 背景说明:
在xml 文件里定义控件的属性,我们用的最多的是 Android系统自带的属性如:
<ImageView android:id="@+id/iv_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@null" android:src="@drawable/ic_ms_quick_order" />
这里小吕将自我学习与分享如何自定义属性<通常在自定义控件中会被使用到>,在xml布局文件中 如:
<!-- 搜索 --> <com.ice.view.menubutton.MyMenuButton xmlns:ice="http://schemas.android.com/apk/res/com.ice.view.menubutton" android:id="@+id/btn_search" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" ice:menuIcon="@drawable/ic_ms_search" ice:menuText="@string/ms_search" ice:textSize="14sp" ice:textColor="@color/orange" ice:btnCode="search" />说明:1. 上面的MyMenuButton 是我自定义的一个菜单按钮控件 <图片和文字的组合控件>。
2. xmlns:ice=http://schemas.android.com/apk/res/com.ice.view.menubutton
是我自定义的命名空间 命名空间的名字可以自己随便定义 ,这里我定义的是ice 及 xmlns:ice 。
注意:
后面的地址则有限制,
其开始必须为:"http://schemas.android.com/apk/res/",后面则是包名com.ice.view.menubutton,
此处的包名与AndroidManifest.xml中
<manifest>节点的属性package="com.ice.view.menubutton"一致,不是自定义控件Java代码所在的包。
3. menuIcon / menuText / textSize / textColor / btnCode 就是我自定义的属性。
<只针对自定义控件 MyMenuButton有效>。
二、关于该自定义控件的开发和xml布局文件的配置大致步骤如下:
1、首先在res/values 文件下定义一个attrs.xml 文件.定义控件的自定义属性集合 代码如下:
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name ="MyMenuButton"> <!-- 图标 --> <attr name="menuIcon" format="reference" /> <!-- 文字 --> <attr name="menuText" format="reference" /> <!-- 文字大小 --> <attr name="textSize" format="dimension" /> <!-- 字体颜色 --> <attr name="textColor" format="color" /> <!-- 页面编号 --> <attr name="btnCode"> <flag name="quickOrder" value="0"></flag> <flag name="orderManager" value="1"></flag> <flag name="favorite" value="2"></flag> <flag name="search" value="3"></flag> </attr> </declare-styleable> </resources>
说明: 1.declare-styleable 是定义自定义属性集合名称的节点元素
2.format可选项
"reference"//引用
"color"//颜色
"boolean"//布尔值
"dimension"//尺寸值
"float"//浮点值
"integer"//整型值
"string"//字符串
"fraction"//百分数,比如200%
3.元素节点 attr 定义各自定义属性名称 format用来定义属性值的类型值,可以指定多种类型值如:
<attr name = "background" format ="reference|color" />
4.枚举值,格式如下:
<attrn ame="orientation">
<enum name="horizontal" value="0" />
<enum name="vertical" value="1" />
</attr>
xml中使用时:
android:orientation= "vertical"
5.标志位,位或运算,格式如下:
<!-- 页面编号 --> <attr name="btnCode"> <flag name="quickOrder" value="0"></flag> <flag name="orderManager" value="1"></flag> <flag name="favorite" value="2"></flag> <flag name="search" value="3"></flag> </attr>
Xml中使用时:
ice:btnCode="search"
2.在res/layout文件下新建自定义控件的xml布局文件:ms_menu_button.xml 代码如下:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:gravity="center_horizontal" android:orientation="vertical" android:background="@null" > <!-- 图标 --> <ImageView android:id="@+id/iv_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@null" android:src="@drawable/ic_ms_quick_order" /> <!-- 文字 --> <TextView android:id="@+id/tv_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/ms_quick_order" /> </LinearLayout> </RelativeLayout>
package com.ice.view.menubutton; import android.content.Context; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; /** * 自定义 菜单按钮 * @author ice * */ public class MyMenuButton extends RelativeLayout { private static final String TAG = "MyMenuButton"; RelativeLayout relativeLayout; ImageView iv_icon; TextView tv_text; private Drawable menuIcon; private CharSequence menuText; private float textSize; private int textColor; private int btnCode; private static final int PAGE_CODE_QUICK_ORDER = 0; // 快速订单 private static final int PAGE_CODE_ORDER_MANAGER = PAGE_CODE_QUICK_ORDER + 1; // 订单管理 private static final int PAGE_CODE_FAVORITE = PAGE_CODE_ORDER_MANAGER + 1; // 我的收藏 private static final int PAGE_CODE_SEARCH = PAGE_CODE_FAVORITE + 1; // 快速查找 public MyMenuButton(Context context) { this(context,null); } public MyMenuButton(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MyMenuButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); Log.d(TAG, "自定义组件构造方法MyMenuButton(...) invoke"); // 获取所有自定义属性组 TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyMenuButton, defStyle, 0); // 获取自定义组件所在布局文件中的自定义属性值 menuIcon = typedArray.getDrawable(R.styleable.MyMenuButton_menuIcon); menuText = typedArray.getText(R.styleable.MyMenuButton_menuText); // 设置当没有设置textSize属性值时 默认字体大小为14px 注意这里的单位是px textSize = typedArray.getDimension(R.styleable.MyMenuButton_textSize, 14); textColor = typedArray.getInt(R.styleable.MyMenuButton_textColor, 0XFFFFFFFF); btnCode = typedArray.getInt(R.styleable.MyMenuButton_btnCode, PAGE_CODE_QUICK_ORDER); relativeLayout = (RelativeLayout) LayoutInflater.from(context).inflate(R.layout.ms_menu_button, this, true); // TypedArray 通常最后调用 .recycle() 方法,为了保持以后使用该属性一致性! typedArray.recycle(); } /** * 当View中所有的子控件均映射成XML后触发 */ @Override protected void onFinishInflate() { super.onFinishInflate(); Log.d(TAG, "onFinishInflate invoke"); iv_icon = (ImageView) relativeLayout.findViewById(R.id.iv_icon); tv_text = (TextView) relativeLayout.findViewById(R.id.tv_text); iv_icon.setImageDrawable(menuIcon); tv_text.setText(menuText); tv_text.setTextColor(textColor); tv_text.setTextSize(textSize); Log.d(TAG, "menuText: "+menuText+" | textSize: "+textSize); this.setOnClickListener(new OnClickEvent()); } class OnClickEvent implements OnClickListener{ @Override public void onClick(View v) { switch (btnCode) { case PAGE_CODE_QUICK_ORDER: Log.d(TAG, "快速下单MenuButton被点击"); break; case PAGE_CODE_ORDER_MANAGER: Log.d(TAG, "订单管理MenuButton被点击"); break; case PAGE_CODE_FAVORITE: Log.d(TAG, "我的收藏MenuButton被点击"); break; case PAGE_CODE_SEARCH: Log.d(TAG, "搜索MenuButton被点击"); break; } } } }
package com.ice.view.menubutton; import android.app.Activity; import android.os.Bundle; import android.util.Log; public class MainActivity extends Activity { private static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d(TAG, "Before setContentView()..."); setContentView(R.layout.activity_main); Log.d(TAG, "After setContentView()..."); } }
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/bg_ms_menu" android:gravity="bottom" android:orientation="horizontal" android:paddingLeft="10dp" android:paddingRight="10dp" > <!-- 快速下单 --> <com.ice.view.menubutton.MyMenuButton xmlns:ice="http://schemas.android.com/apk/res/com.ice.view.menubutton" android:id="@+id/btn_quick_order" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" ice:menuIcon="@drawable/ic_ms_quick_order" ice:menuText="@string/ms_quick_order" ice:textColor="@android:color/black" ice:btnCode="quickOrder"/> <!-- 订单管理 --> <com.ice.view.menubutton.MyMenuButton xmlns:ice="http://schemas.android.com/apk/res/com.ice.view.menubutton" android:id="@+id/btn_order_manager" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" ice:menuIcon="@drawable/ic_ms_order_manager" ice:menuText="@string/ms_order_manager" ice:textColor="@color/green" ice:btnCode="orderManager" /> <!-- 我的收藏 --> <com.ice.view.menubutton.MyMenuButton xmlns:ice="http://schemas.android.com/apk/res/com.ice.view.menubutton" android:id="@+id/btn_my_favorite" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" ice:menuIcon="@drawable/ic_ms_my_favorite" ice:menuText="@string/ms_my_favorite" ice:textColor="@color/red" ice:textSize="14px" ice:btnCode="favorite" /> <!-- 搜索 --> <com.ice.view.menubutton.MyMenuButton xmlns:ice="http://schemas.android.com/apk/res/com.ice.view.menubutton" android:id="@+id/btn_search" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" ice:menuIcon="@drawable/ic_ms_search" ice:menuText="@string/ms_search" ice:textSize="14sp" ice:textColor="@color/orange" ice:btnCode="search" /> </LinearLayout >
--------------》 哈哈 这里搜索menuButton怎么那么另类呢、呵呵 这是小吕故意的 详细请看activity_main.xml和MyMenuButton.java代码说明。
7.点击自定义菜单控件 后台日志信息如下:
说明:这里我们可以看到自定义组件、onFinishInflate()方法的运行情况。
最后 附上本篇源码地址:http://download.csdn.net/detail/l416112167/7549299