自定义组合view的编写是我们在做Android开发的时候必须会的一项技能。例如:你写好了一个布局文件,但是第二天“老板”告诉你,需求变了,还要加两个除了文本不一样之外其他都一样的item,第三天亦是如此,你怎么办?Ctrl C、Ctrl V?这样是行不通的,直接复制粘贴带来的后果就是你要初始化非常多的控件,得不偿失。这样的情况下就需要我们自己定义一个组合view。
我们都知道Android Studio与Eclipse其实差不多,但是还是存在一些微小的差异。
下面来看一下具体的实现:
假如某个页面有这样的item4个
首先编写上图中item的布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rl_show_address"
android:layout_width="match_parent"
android:layout_height="60dip"
android:background="@drawable/selector_blue" >
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dip"
android:layout_marginTop="1dip"
android:text="这是标题"
android:textColor="#000000"
android:textSize="20sp" />
<TextView
android:id="@+id/tv_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tv_title"
android:layout_marginLeft="6dip"
android:layout_marginTop="1dip"
android:text="这是描述内容"
android:textColor="#99ff0000"
android:textSize="14sp" />
<CheckBox
android:id="@+id/cb_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:clickable="false"
android:focusable="false" />
<!-- 加一条分割线 -->
<View
android:layout_marginTop="7dip"
android:layout_alignParentBottom="true"
android:layout_alignBottom="@id/cb_status"
android:layout_width="match_parent"
android:layout_height="0.2dip"
android:background="#000000"/>
</RelativeLayout>
然后编写activity_main.xml,编写的时候一定要注意重命名空间里面直接用包名即可,这样做的缺点是无法打包发布。目前我还没有找到比较理想的解决方法。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:example="com.kaipingzhou.testview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.kaipingzhou.testview.MyView
android:id="@+id/cv_first"
android:layout_width="match_parent"
android:layout_height="wrap_content"
example:desc_off="我是未被选中的描述1"
example:desc_on="我是被选中的描述1"
example:title="我是标题1" >
</com.kaipingzhou.testview.MyView>
<com.kaipingzhou.testview.MyView
android:id="@+id/cv_second"
android:layout_width="match_parent"
android:layout_height="wrap_content"
example:desc_off="我是未被选中的描述2"
example:desc_on="我是被选中的描述2"
example:title="我是标题2" >
</com.kaipingzhou.testview.MyView>
<com.kaipingzhou.testview.MyView
android:id="@+id/cv_third"
android:layout_width="match_parent"
android:layout_height="wrap_content"
example:desc_off="我是未被选中的描述3"
example:desc_on="我是被选中的描述3"
example:title="我是标题3" >
</com.kaipingzhou.testview.MyView>
<com.kaipingzhou.testview.MyView
android:id="@+id/cv_fourth"
android:layout_width="match_parent"
android:layout_height="wrap_content"
example:desc_off="我是未被选中的描述4"
example:desc_on="我是被选中的描述4"
example:title="我是标题4" >
</com.kaipingzhou.testview.MyView>
</LinearLayout>
在values中新建attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="myview">
<attr name="desc_on" format="string"></attr>
<attr name="desc_off" format="string"></attr>
<attr name="title" format="string"></attr>
</declare-styleable>
</resources>
下面是自定义view的类,取名叫MyView
package com.kaipingzhou.testview;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.CheckBox;
import android.widget.RelativeLayout;
import android.widget.TextView;
/**
* Created by KaipingZhou on 2017/2/21.
*/
public class MyView extends RelativeLayout {
private TextView tv_title;
private TextView tv_desc;
private CheckBox cb_status;
private String namespace = "com.kaipingzhou.testview";
private String title;
private String desc_on;
private String desc_off;
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
View view = View.inflate(context, R.layout.my_view, this);
tv_title = (TextView) view.findViewById(R.id.tv_title);
tv_desc = (TextView) view.findViewById(R.id.tv_desc);
cb_status = (CheckBox) view.findViewById(R.id.cb_status);
title = attrs.getAttributeValue(namespace, "title");
desc_on = attrs.getAttributeValue(namespace, "desc_on");
desc_off = attrs.getAttributeValue(namespace, "desc_off");
System.out.println(title + ":" + desc_on + ":" + desc_off);
if (title != null) {
tv_title.setText(title);
}
if (desc_off != null) {
tv_desc.setText(desc_off);
}
}
public boolean isChecked() {
return cb_status.isChecked();
}
public void setChecked(boolean isChecked) {
cb_status.setChecked(isChecked);
if (isChecked) {
tv_desc.setText(desc_on);
} else {
tv_desc.setText(desc_off);
}
}
}
MianActivity中这样写:
package com.kaipingzhou.testview;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends Activity implements View.OnClickListener{
private MyView cv_first;
private MyView cv_second;
private MyView cv_third;
private MyView cv_fourth;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cv_first = (MyView) findViewById(R.id.cv_first);
cv_second = (MyView) findViewById(R.id.cv_second);
cv_third = (MyView) findViewById(R.id.cv_third);
cv_fourth = (MyView) findViewById(R.id.cv_fourth);
cv_first.setOnClickListener(this);
cv_second.setOnClickListener(this);
cv_third.setOnClickListener(this);
cv_fourth.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.cv_first:
if (cv_first.isChecked()) {
cv_first.setChecked(false);
} else {
cv_first.setChecked(true);
}
break;
case R.id.cv_second:
if (cv_second.isChecked()) {
cv_second.setChecked(false);
} else {
cv_second.setChecked(true);
}
break;
case R.id.cv_third:
if (cv_third.isChecked()) {
cv_third.setChecked(false);
} else {
cv_third.setChecked(true);
}
break;
case R.id.cv_fourth:
if (cv_fourth.isChecked()) {
cv_fourth.setChecked(false);
} else {
cv_fourth.setChecked(true);
}
break;
default:
break;
}
}
}
运行结果如下: