转载自:http://blog.csdn.net/smartbetter/article/details/50642730 侵删
为了能让代码能够更多的复用,故使用自定义组合控件。下面是一个"提示更新"自定义组合控件的实现。
一、应用场景(提高代码复用)
二、代码实现(以“提示更新自定义组合控件”为例)
1.创建一个java类SettingView,继承RelativeLayout,实现三个构造函数,并创建一个init方法,在构造函数中调用,在init方法中添加布局文件
- package com.example.settingview;
- import android.content.Context;
- import android.util.AttributeSet;
- import android.view.View;
- import android.widget.CheckBox;
- import android.widget.RelativeLayout;
- import android.widget.TextView;
- public class SettingView extends RelativeLayout {
- private TextView tv_setting_title;
- private TextView tv_setting_des;
- private CheckBox cb_setting_ischecked;
- private String des_on;
- private String des_off;
- //在代码调用的时候使用
- public SettingView(Context context) {
- super(context);
- init();
- }
- //在布局文件中使用的时候调用,比两个参数的多个样式文件
- public SettingView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- init();
- }
- //在布局文件中使用的时候调用
- public SettingView(Context context, AttributeSet attrs) {
- super(context, attrs);
- init();
- String title = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.example.settingview", "title");
- des_on = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.example.settingview", "des_on");
- des_off = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.example.settingview", "des_off");
- //设置控件的值
- tv_setting_title.setText(title);
- if (isChecked()) {
- tv_setting_des.setText(des_on);
- }else{
- tv_setting_des.setText(des_off);
- }
- }
- /**
- * 添加布局文件
- */
- private void init(){
- //添加布局文件的操作
- // TextView textView = new TextView(getContext());
- // textView.setText("我是自定义组合控件的textview");
- //第一种方式
- //将布局文件转化成view对象
- // View view = View.inflate(getContext(), R.layout.settingview, null);//先有爹,再去添加孩子,亲生的
- // //添加
- // this.addView(view);//在相对布局中添加了textview
- //第二种方式
- //给转化的view对象,找个父控件,先转化成view对象,在添加到布局文件中
- View view = View.inflate(getContext(), R.layout.settingview, this);//先有孩子,再去找爹,喜当爹
- //初始化控件
- tv_setting_title = (TextView) view.findViewById(R.id.tv_setting_title);
- tv_setting_des = (TextView) view.findViewById(R.id.tv_setting_des);
- cb_setting_ischecked = (CheckBox) view.findViewById(R.id.cb_setting_ischecked);
- }
- /**
- * 设置标题
- * @param title
- */
- public void setTitle(String title){
- tv_setting_title.setText(title);
- }
- /**
- * 设置描述信息
- * @param des
- */
- public void setDes(String des){
- tv_setting_des.setText(des);
- }
- /**
- * 设置checkbox的状态
- * @param isChecked
- */
- public void setChecked(boolean isChecked){
- cb_setting_ischecked.setChecked(isChecked);
- //相当于把sv_setting_update.setDes("已打开提示更新");封装到了setChecked方法中
- if (isChecked()) {
- tv_setting_des.setText(des_on);
- }else{
- tv_setting_des.setText(des_off);
- }
- }
- /**
- * 获取checkbox的状态
- * @return
- */
- public boolean isChecked(){
- return cb_setting_ischecked.isChecked();
- }
- }<span style="font-size:14px;">
- </span>
2.MainActivity.java代码
- package com.example.settingview;
- import android.app.Activity;
- import android.content.SharedPreferences;
- import android.content.SharedPreferences.Editor;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- public class MainActivity extends Activity {
- private SettingView sv_setting_update;
- private SharedPreferences sp;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_setting);
- sp = getSharedPreferences("config", MODE_PRIVATE);
- sv_setting_update = (SettingView) findViewById(R.id.sv_setting_update);
- update();
- }
- /**
- * 提示更新
- */
- private void update() {
- // 初始化自定义组合控件中的控件的默认值
- // sv_setting_update.setTitle("提示更新");
- // getBoolean : 从sp中获取名称是update的数据信息,defValue:如果没有找到就是defValue,缺省值
- if (sp.getBoolean("update", true)) {
- // sv_setting_update.setDes("已打开提示更新");
- sv_setting_update.setChecked(true);
- } else {
- // sv_setting_update.setDes("已关闭提示更新");
- sv_setting_update.setChecked(false);
- }
- // 给自定义组合控件设置点击事件
- sv_setting_update.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Editor edit = sp.edit();
- // isChecked() : 获取当前checkbox的状态
- if (sv_setting_update.isChecked()) {
- // 关闭操作
- sv_setting_update.setChecked(false);
- // sv_setting_update.setDes("已关闭提示更新");
- // 保存状态
- edit.putBoolean("update", false);
- // edit.apply();//保存到文件中的,但是仅限于9版本之上,9版本之下保存在内存
- } else {
- // 打开操作
- sv_setting_update.setChecked(true);
- // sv_setting_update.setDes("已打开提示更新");
- edit.putBoolean("update", true);
- }
- edit.commit();
- }
- });
- }
- }
3.res资源文件代码
values/attrs.xml
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <!-- 自定义属性 -->
- <!-- 在activity_setting.xml中使用 -->
- <declare-styleable name="com.example.settingview.ui.SettingView">
- <attr name="title" format="string" /> <!-- format : 类型 -->
- <attr name="des_on" format="string" />
- <attr name="des_off" format="string" />
- </declare-styleable>
- </resources>
layout/settingview.xml
- <?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" >
- <!-- layout_margin : 距离父控件上下左右边框的距离 -->
- <TextView
- android:id="@+id/tv_setting_title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="5dp"
- android:text="提示更新"
- android:textSize="18sp" />
- <TextView
- android:id="@+id/tv_setting_des"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@id/tv_setting_title"
- android:layout_marginLeft="5dp"
- android:text="已关闭提示更新"
- android:textColor="#aa000000"
- android:textSize="16sp" />
- <!-- checkbox天生带有点击事件和获取焦点的事件
- focusable :是否可以获取焦点,false:不可以 true:可以
- clickable : 是否可以点击 false:不可以 true:可以
- -->
- <CheckBox
- android:id="@+id/cb_setting_ischecked"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_centerVertical="true"
- android:layout_marginRight="18dp"
- android:focusable="false"
- android:clickable="false"
- />
- <!-- layout_marginTop : 距离距离控件顶部的距离 -->
- <View
- android:layout_width="match_parent"
- android:layout_height="0.5dp"
- android:layout_below="@id/tv_setting_des"
- android:layout_marginTop="5dp"
- android:background="#77000000" />
- </RelativeLayout>
layout/activity_setting.xml
- <?xml version="1.0" encoding="utf-8"?>
- <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:example="http://schemas.android.com/apk/res/com.example.settingview"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
- <!-- ScrollView : 只能有一个子控件,当屏幕放不下条目的时候,就会让屏幕,可以看到的时候就不会滑动-->
- <!-- 自定义属性 -->
- <!-- 系统用来声明属性用的:sdk\platforms\android-18\data\res\values\attrs.xml -->
- <com.example.settingview.SettingView
- android:id="@+id/sv_setting_update"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- example:des_off="已关闭提示更新"
- example:des_on="已打开提示更新"
- example:title="提示更新" >
- </com.example.settingview.SettingView>
- </ScrollView>
4.我们运行一下,效果如下