一、内容描述
根据“慕课网”上的教程,实现一个自定义的View,且该View中使用自定义的属性,同时为该自定义的View定义点击事件的回调方法。
二、定义自定义的属性
在res/valus/ 文件夹下创建一个 attrs.xml 的属性定义文件,内容如下:
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="HeadBar"> <attr name="leftButtonText" format="string" /> <attr name="leftButtonTextColor" format="color|reference" /> <attr name="leftButtonTextSize" format="dimension"></attr> <attr name="centerTextViewText" format="string"></attr> <attr name="centerTextViewTextSize" format="dimension"></attr> <attr name="centerTextViewColor" format="color|reference"></attr> <attr name="rightButtonText" format="string" /> <attr name="rightButtonTextColor" format="color|reference" /> <attr name="rightButtonTextSize" format="dimension"></attr> </declare-styleable>
<attr name="backgroud_color" format="string"></attr>
<attr name="bc" format="color|reference"></attr>
</resources>
三、定义使用它的布局文件
这里使用MainActivity的activity_main.xml,内容如下,
其中 xmlns:lib="http://schemas.android.com/apk/res-auto" 一行是定义一个第三方库的名字空间,本例中即为了可以使用自定义的属性
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <com.baidu.lulei.customview.HeadBar xmlns:lib="http://schemas.android.com/apk/res/com.baidu.lulei.customview" android:id="@+id/headbar" android:layout_width="match_parent" android:layout_height="match_parent" lib:backgroud_color="backgroud_color" lib:bc="#000011" lib:centerTextViewColor="#ff00ff" lib:centerTextViewText="标题" lib:centerTextViewTextSize="20sp" lib:leftButtonText="返回" lib:leftButtonTextColor="#ff0000" lib:leftButtonTextSize="20sp" lib:rightButtonText="分享" lib:rightButtonTextColor="#0000ff" lib:rightButtonTextSize="20sp" > </com.baidu.lulei.customview.HeadBar> </RelativeLayout>
四、自定义 HeadBar 类型的View
本例中是它继承自RelativeLayout,因为本例中自定义的View本质上它类似一个容器,为了方便布局,这里使用才集成字RelativeLayout,当然你也可以继承自其它类型的ViewGroup
istener(new OnClickListener() {
@Override public void onClick(View v) { if (listener != null) listener.leftButtonClick(v); } }); rightButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (listener != null) listener.rightButtonClick(v); } }); this.centerText.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (listener != null) listener.centerTextViewClick(v); } }); } public static interface ClickListerner { public void leftButtonClick(View v); public void rightButtonClick(View v); public void centerTextViewClick(View v); } }
五、测试它
从上面的activity_main.xml 布局文件中可以看到,它内部使用了一个自定义类型的HeadBar的View,所以可以在MainActivity中测试它,可以看到我们可以在外部定一个回调方法给自定义的View使用。
package com.baidu.lulei.customview; import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.RelativeLayout; import android.widget.TextView; public class HeadBar extends RelativeLayout { private Button leftButton; private Button rightButton; private TextView centerText; private ClickListerner listener; public void setListener(ClickListerner listener) { this.listener = listener; } public HeadBar(Context context, AttributeSet attrs) { super(context, attrs); leftButton = new Button(context); rightButton = new Button(context); centerText = new TextView(context); TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.HeadBar); String backgroundcolor = attrs .getAttributeValue( "http://schemas.android.com/apk/res/com.baidu.lulei.customview", "backgroud_color"); int bc = attrs .getAttributeIntValue( "http://schemas.android.com/apk/res/com.baidu.lulei.customview", "bc", 0xff0000ff); Log.e("Log", "bc :" + bc); Log.e("Log", "backgroundcolor :" + backgroundcolor); // 初始化左边的那个button int leftButtonTextColor = ta.getColor( R.styleable.HeadBar_leftButtonTextColor, 0x000011); String leftButtonText = ta .getString(R.styleable.HeadBar_leftButtonText); float leftButtonTextSize = ta.getDimension( R.styleable.HeadBar_leftButtonTextSize, 20); leftButton.setText(leftButtonText); leftButton.setTextSize(leftButtonTextSize); leftButton.setTextColor(leftButtonTextColor); // 初始化右边的那个button int rightButtonTextColor = ta.getColor( R.styleable.HeadBar_rightButtonTextColor, 0xff0000ff); String rightButtonText = ta .getString(R.styleable.HeadBar_rightButtonText); float rightButtonTextSize = ta.getDimension( R.styleable.HeadBar_rightButtonTextSize, 20); rightButton.setText(rightButtonText); rightButton.setTextSize(rightButtonTextSize); rightButton.setTextColor(rightButtonTextColor); // 初始化中间的TextView int centerTextColor = ta.getColor( R.styleable.HeadBar_centerTextViewColor, 0xff000000); String centerText = ta .getString(R.styleable.HeadBar_centerTextViewText); float centerTextSize = ta.getDimension( R.styleable.HeadBar_centerTextViewTextSize, 20); this.centerText.setText(centerText); this.centerText.setTextSize(centerTextSize); this.centerText.setTextColor(centerTextColor); // 释放TypedArray ta.recycle(); // 开始布局 RelativeLayout.LayoutParams leftButtonLayoutParams = new LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); leftButtonLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT); leftButton.setLayoutParams(leftButtonLayoutParams); RelativeLayout.LayoutParams rightButtonLayoutParams = new LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); rightButtonLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); rightButton.setLayoutParams(rightButtonLayoutParams); RelativeLayout.LayoutParams centerTextLayoutParams = new LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); centerTextLayoutParams.addRule(RelativeLayout.CENTER_IN_PARENT); centerTextLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP); this.centerText.setLayoutParams(centerTextLayoutParams); Log.e("Tag", "" + leftButton.getId()); // 将布局好的三个控件放入自定义的view中去 addView(leftButton); addView(rightButton); addView(this.centerText); // 添加点击事件 leftButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (listener != null) listener.leftButtonClick(v); } }); rightButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (listener != null) listener.rightButtonClick(v); } }); this.centerText.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (listener != null) listener.centerTextViewClick(v); } }); } public static interface ClickListerner { public void leftButtonClick(View v); public void rightButtonClick(View v); public void centerTextViewClick(View v); } }
六、效果
七、注意
1. 常见自定义属性的值类型有哪些?
属性类型 |
使用demo |
<attr name = "background" format = "reference" /> |
android:background = "@drawable/图片ID" |
<attr name = "textColor" format = "color" /> |
android:textColor = "#00FF00" |
<attr name = "focusable" format = "boolean" /> |
android:focusable = "true|false" |
<attr name = "layout_width" format = "dimension" /> |
android:layout_width = "42dip|42sp|42px" |
<attr name = "fromAlpha" format = "float" /> |
android:fromAlpha = "1.0" |
<attr name = "frameDuration" weight="integer" /> |
android:weight = "12" |
<attr name = "apiKey" format = "string" /> |
android:apiKey = "this_is_a_string" |
<attr name = "pivotX" format = "fraction" /> |
android:pivotX = "200%" |
<attr name="orientation"> <enum name="horizontal" value="0" /> <enum name="vertical" value="1" /> </attr> |
android:orientation = "vertical" |
<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" /> </attr> |
android:windowSoftInputMode = "stateHidden"> |
2. attrs.xml中自己使用<attr/>标签的属性怎么获取?
如下两个属性,声明在declare-styleable之外,获取它的值呢?
声明:
<attr name="backgroud_color" format="string"></attr>
<attr name="bc" format="color|reference"></attr>
使用:
注意现在lib是 名字空间 xmlns:lib="http://schemas.android.com/apk/res/"+"应用包名" 的形式
lib:bc="#000011"
lib:backgroud_color="backgroud_color"
获取:
String backgroundcolor = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.baidu.lulei.customview","backgroud_color");
int bc = attrs.getAttributeIntValue("http://schemas.android.com/apk/res/com.baidu.lulei.customview","bc", 0xff0000ff);
3. 读取自定义属性时使用的自定义空间命名规则如何?
如果都是在declare-styleable中声明的属性,那么名字空间可以使用
http://schemas.android.com/apk/res/+”应用包名” 或者 http://schemas.android.com/apk/res-auto
而如果你使用自定义属性是在attr中单独定义的,那么请你使用前者。
4. 附源代码下载 https://github.com/LuLei2013/CustomView.git