看这段代码
<com.cskaoyan.mobilemanager.ui.SettingItem android:id="@+id/settingitem_autoupdate" android:layout_width="fill_parent" android:layout_height="wrap_content"/>
这是我们的自定义控件,这个控件相当于一个view,将几个子控件组合起来显示,其对应的控件代码,settingItem,是继承于RelativeLayout的,随意才能使用他的父级的一些属性,id、width等
但是我们希望这个控件能够拥有自己的一些属性,为什么系统的这些能够调用这么多属性,因为他有自己的命名空间,在其中定义了很多属性
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
这是安卓scheme约束中已经提到的
每个工程中都要用到SDK,也就是jar包,这其中包含了所有相关文件
然后去SDK中看,其实也就是命名空间namespace指向的,定义了所有能用的属性
OK,那么我们也应该弄一个命名空间,定义属性,再来调用
在values里新建一个attrs.xml,由于在后续的开发中要多次用到title以及checkbox的勾选与否,所以要在这定义
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="com.rjl.mobilephonemanager.ui.SettingItem"> <attr name="itemtitle" format="string"/> </declare-styleable> </resources>
然后在需要的layout里指向这个命名空间,例如之前我们的activity_setting里,这个命名空间最后的名称应该是在manifest里定义的包名,而不是工程里的包名,一定要注意
系统需要初始化对应的类来调用控件,我们要在这个类里面去定义这些属性,本项目中UI包下的settingItem类
系统把layout里调用的属性传到settingItem的第二个方法里,我们一共写了4个,可以打trace看看
public SettingItem(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub init(); int c = attrs.getAttributeCount(); String attr0= attrs.getAttributeName(0); String attr1= attrs.getAttributeName(1); String attr2= attrs.getAttributeName(2); String attr3= attrs.getAttributeName(3); System.out.println("SettingItem.SettingItem()"+c+":"+attr0 +attr1+attr2+attr3);
现在来初始化我们自己的控件,要去掉在子控件item_setting里写死的title"自动更新"
在第二个方法里找到属性,在初始化方法里去初始化,然后第二个方法里再显示出来
接下来,添加checkbox的勾选与否的功能
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="com.rjl.mobilephonemanager.ui.SettingItem"> <attr name="itemtitle" format="string"/> <attr name="desc_checkbox_on" format="string"/> <attr name="desc_checkbox_off" format="string"/> </declare-styleable> </resources>
<com.rjl.mobilephonemanager.ui.SettingItem android:id="@+id/settingitem_autoupdate" android:layout_width="fill_parent" android:layout_height="wrap_content" rjl:itemtitle="自动更新" rjl:desc_checkbox_on="自动更新开启" rjl:desc_checkbox_off="自动更新关闭"/>
控件
public class SettingItem extends RelativeLayout { private TextView tv_setting_title; private TextView tv_setting_description; private String desc_checkbox_on; private String desc_checkbox_off; public SettingItem(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub init(); } public SettingItem(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub init(); int c = attrs.getAttributeCount(); String attr0= attrs.getAttributeName(0); String attr1= attrs.getAttributeName(1); String attr2= attrs.getAttributeName(2); String attr3= attrs.getAttributeName(3); System.out.println("SettingItem.SettingItem()"+c+":"+attr0 +attr1+attr2+attr3); String itemname = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.rjl.mobilephonemanager", "itemtitle"); desc_checkbox_on = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.rjl.mobilephonemanager", "desc_checkbox_on"); desc_checkbox_off = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.rjl.mobilephonemanager", "desc_checkbox_off"); tv_setting_title.setText(itemname); } public SettingItem(Context context) { super(context); // TODO Auto-generated constructor stub init(); } //初始化,三个构造函数都需要调用它 //通过这个初始化,通过填充器将三个控件填充到这个view,再将view加入到组合控件里 //在activity_setting里组合,另需一个setting_item来实现原来的三个控件 private void init() { // TODO Auto-generated method stub /*View view= View.inflate(getContext(), R.layout.setting_item, null); //将控件的view加载到这个view上 this.addView(view);*/ View v= View.inflate(getContext(), R.layout.setting_item, this); tv_setting_title = (TextView) v.findViewById(R.id.tv_setting_title); tv_setting_description = (TextView) v.findViewById(R.id.tv_setting_description); } public void setdescription(String text){ tv_setting_description.setText(text); } public void setdescriptionon(){ tv_setting_description.setText(desc_checkbox_on); } public void setdescriptionoff(){ tv_setting_description.setText(desc_checkbox_off); } }
layout 有一个小bug,点击小框框无效,那我们就去把checkbox的onclicklisten关了,当然重写也可以
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/tv_setting_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="5dp" android:textSize="20sp"/> <TextView android:id="@+id/tv_setting_description" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="16sp" android:layout_marginLeft="5dp" android:layout_below="@id/tv_setting_title"/> <CheckBox android:id="@+id/cb_settingitem" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:focusable="false" android:clickable="false"/> </RelativeLayout>
settingactivity里的调用
public class SettingActivity extends Activity { private CheckBox cb; private SettingItem settingItem ; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.activity_setting); final SharedPreferences sp = getSharedPreferences("config", MODE_PRIVATE); settingItem = (SettingItem) findViewById(R.id.settingitem_autoupdate); cb = (CheckBox) settingItem.findViewById(R.id.cb_settingitem); //默认是true boolean ischeck= sp.getBoolean("autoupdate", true); cb.setChecked(ischeck); if (ischeck) { settingItem.setdescriptionon(); } else { settingItem.setdescriptionoff(); } settingItem.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Editor editor = sp.edit(); if(cb.isChecked()){ //勾上点击后要置成false cb.setChecked(false); settingItem.setdescriptionoff(); editor.putBoolean("autoupdate", false); }else{ cb.setChecked(true); settingItem.setdescriptionon(); editor.putBoolean("autoupdate", true); } editor.commit(); } }); } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:rjl="http://schemas.android.com/apk/res/com.rjl.mobilephonemanager" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="60dp" android:text="设置中心" android:background="#00FF00" android:gravity="center" android:textSize="25sp" /> <com.rjl.mobilephonemanager.ui.SettingItem android:id="@+id/settingitem_autoupdate" android:layout_width="fill_parent" android:layout_height="wrap_content" rjl:itemtitle="自动更新" rjl:desc_checkbox_on="自动更新开启" rjl:desc_checkbox_off="自动更新关闭"/> </LinearLayout>