首先介绍在实际开发过程中遇到的问题:
在写布局的过程中发现有一些布局很相似。区别只是文本显示的内容等等。如下所示:
注:如上代码虽然可以使用RadioGroup+radioButton实现。但为了更好的调节布局我们使用ImageView+TextView
原始代码实现:
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:layout_weight="1"
>
<ImageView
android:id="@+id/im_radio_button"
android:layout_width="34dp"
android:layout_height="34dp"
android:layout_gravity="center"
android:background="@drawable/btn_message"
/>
<TextView
android:id="@+id/tv_radio_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="消息"
android:textSize="12sp"
/>
</LinearLayout>
如上代码很简单,要实现图片所以。只需要将其复制四份,给予不同的选择器和文本即可。
于是我们思考既然布局很多地方都相似我们能不能把其相似的代码抽取出来而不用重复的写相同的代码。
首先把共同的布局代码抽取出来,写一个单独的XML布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:layout_weight="1"
>
<ImageView
android:id="@+id/im_radio_button"
android:layout_width="34dp"
android:layout_height="34dp"
android:layout_gravity="center"
/>
<TextView
android:id="@+id/tv_radio_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12sp"
/>
</LinearLayout>
<TextView
android:id="@+id/tv_noreadmessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginRight="3dp"
android:layout_marginTop="3dp"
android:gravity="center"
android:background="@mipmap/no_readmessagebk <TextView
android:id="@+id/tv_noreadmessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginRight="3dp"
android:layout_marginTop="3dp"
android:gravity="center"
android:textColor="#ffffffff"
android:textSize="10sp"
/>"
android:textColor="#ffffffff"
android:textSize="10sp"
/>
</LinearLayout>
现在自定义一个布局ButtomRadioButton(自定义布局中加载上述的布局XML)以及修改原来的布局文件:
<com.example.wang.view.ButtomRadioButton
android:id="@+id/btn_message"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
weichatAttr:radioButtonDrawable="@drawable/btn_message_selector"
weichatAttr:radioButtonText="消息"
weichatAttr:radioButtonNoReadMessage="1"
>
</com.example.wang.view.ButtomRadioButton>
<com.example.wang.view.ButtomRadioButton
android:id="@+id/btn_contacts"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
weichatAttr:radioButtonDrawable="@drawable/btn_contacts_selector"
weichatAttr:radioButtonText="通讯录"
weichatAttr:radioButtonNoReadMessage="1"
>
</com.example.wang.view.ButtomRadioButton>
<com.example.wang.view.ButtomRadioButton
android:id="@+id/btn_discover"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
weichatAttr:radioButtonDrawable="@drawable/btn_discover_selector"
weichatAttr:radioButtonText="发现"
weichatAttr:radioButtonNoReadMessage="1"
>
</com.example.wang.view.ButtomRadioButton>
<com.example.wang.view.ButtomRadioButton
android:id="@+id/btn_me"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
weichatAttr:radioButtonDrawable="@drawable/btn_me_selector"
weichatAttr:radioButtonText="我"
weichatAttr:radioButtonNoReadMessage="1"
>
</com.example.wang.view.ButtomRadioButton>
如上使用了自定义属性,关于自定义属性此处不过多解释。
public class ButtomRadioButton extends LinearLayout{
private Context context;
private ImageView im_radio_button;
private TextView tv_radio_button;
private TextView tv_noreadmessage;
private TypedArray typedArray;
public ButtomRadioButton(Context context) {
this(context, null);
}
public ButtomRadioButton(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
typedArray = context.obtainStyledAttributes(attrs,R.styleable.WeichatButtomAttr);
initView();
initData();
}
//初始化各个布局
private void initView(){
View view = View.inflate(getContext(), R.layout.buttom_radio, this);
im_radio_button = (ImageView) view.findViewById(R.id.im_radio_button);
tv_radio_button = (TextView) view.findViewById(R.id.tv_radio_button);
tv_noreadmessage = (TextView) view.findViewById(R.id.tv_noreadmessage);
}
//初始化自定义属性的值
private void initData(){
//设置background
int background_id = typedArray.getResourceId(R.styleable.WeichatButtomAttr_radioButtonDrawable, -1);
System.out.println(background_id);
im_radio_button.setBackgroundResource(background_id);
//设置名称
String tv_name = typedArray.getString(R.styleable.WeichatButtomAttr_radioButtonText);
tv_radio_button.setText(tv_name);
typedArray.recycle();
}
}
通过如上代码则在定义现在布局时代码量减小很多。
备注:关于自定义属性,可以查看 http://blog.youkuaiyun.com/canot/article/details/50541239 这篇文章解释了在Eclipse和AndroidStudio两种IDE使用自定义属性的区别。