【Android】Android Studio中的自定义组合view
自定义组合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; } } }运行结果如下: