android 自定义组合控件

了能让代码能够更多的复用,故使用自定义组合控件。下面是一个"提示更新"自定义组合控件的实现。

一、应用场景(提高代码复用)

二、代码实现(以“提示更新自定义组合控件”为例)

1.创建一个java类SettingView,继承RelativeLayout,实现三个构造函数,并创建一个init方法,在构造函数中调用,在init方法中添加布局文件


  1. package com.example.settingview; 
  2. import android.content.Context; 
  3. import android.util.AttributeSet; 
  4. import android.view.View; 
  5. import android.widget.CheckBox; 
  6. import android.widget.RelativeLayout; 
  7. import android.widget.TextView; 
  8. public class SettingView extends RelativeLayout { 
  9. private TextView tv_setting_title; 
  10. private TextView tv_setting_des; 
  11. private CheckBox cb_setting_ischecked; 
  12. private String des_on; 
  13. private String des_off; 
  14. //在代码调用的时候使用
  15. public SettingView(Context context) { 
  16. super(context); 
  17.         init(); 
  18.     } 
  19. //在布局文件中使用的时候调用,比两个参数的多个样式文件
  20. public SettingView(Context context, AttributeSet attrs, int defStyle) { 
  21. super(context, attrs, defStyle); 
  22.         init(); 
  23.     } 
  24. //在布局文件中使用的时候调用
  25. public SettingView(Context context, AttributeSet attrs) { 
  26. super(context, attrs); 
  27.         init(); 
  28.         String title = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.example.settingview", "title"); 
  29.         des_on = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.example.settingview", "des_on"); 
  30.         des_off = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.example.settingview", "des_off"); 
  31. //设置控件的值
  32.         tv_setting_title.setText(title); 
  33. if (isChecked()) { 
  34.             tv_setting_des.setText(des_on); 
  35.         }else{ 
  36.             tv_setting_des.setText(des_off); 
  37.         } 
  38.     } 
  39. /**
  40.      * 添加布局文件
  41.      */
  42. private void init(){ 
  43. //添加布局文件的操作
  44. //      TextView textView = new TextView(getContext());
  45. //      textView.setText("我是自定义组合控件的textview");
  46. //第一种方式
  47. //将布局文件转化成view对象
  48. //      View view = View.inflate(getContext(), R.layout.settingview, null);//先有爹,再去添加孩子,亲生的
  49. //      //添加
  50. //      this.addView(view);//在相对布局中添加了textview
  51. //第二种方式
  52. //给转化的view对象,找个父控件,先转化成view对象,在添加到布局文件中
  53.         View view = View.inflate(getContext(), R.layout.settingview, this);//先有孩子,再去找爹,喜当爹
  54. //初始化控件
  55.         tv_setting_title = (TextView) view.findViewById(R.id.tv_setting_title); 
  56.         tv_setting_des = (TextView) view.findViewById(R.id.tv_setting_des); 
  57.         cb_setting_ischecked = (CheckBox) view.findViewById(R.id.cb_setting_ischecked); 
  58.     } 
  59. /**
  60.      * 设置标题
  61.      * @param title
  62.      */
  63. public void setTitle(String title){ 
  64.         tv_setting_title.setText(title); 
  65.     } 
  66. /**
  67.      * 设置描述信息
  68.      * @param des
  69.      */
  70. public void setDes(String des){ 
  71.         tv_setting_des.setText(des); 
  72.     } 
  73. /**
  74.      * 设置checkbox的状态
  75.      * @param isChecked
  76.      */
  77. public void setChecked(boolean isChecked){ 
  78.         cb_setting_ischecked.setChecked(isChecked); 
  79. //相当于把sv_setting_update.setDes("已打开提示更新");封装到了setChecked方法中
  80. if (isChecked()) { 
  81.             tv_setting_des.setText(des_on); 
  82.         }else{ 
  83.             tv_setting_des.setText(des_off); 
  84.         } 
  85.     } 
  86. /**
  87.      * 获取checkbox的状态
  88.      * @return
  89.      */
  90. public boolean isChecked(){ 
  91. return cb_setting_ischecked.isChecked(); 
  92.     } 
  93. }<span style="font-size:14px;"> 
  94. </span> 


2.MainActivity.java代码

  1. package com.example.settingview; 
  2. import android.app.Activity; 
  3. import android.content.SharedPreferences; 
  4. import android.content.SharedPreferences.Editor; 
  5. import android.os.Bundle; 
  6. import android.view.View; 
  7. import android.view.View.OnClickListener; 
  8. public class MainActivity extends Activity { 
  9. private SettingView sv_setting_update; 
  10. private SharedPreferences sp; 
  11. @Override
  12. protected void onCreate(Bundle savedInstanceState) { 
  13. super.onCreate(savedInstanceState); 
  14.         setContentView(R.layout.activity_setting); 
  15.         sp = getSharedPreferences("config", MODE_PRIVATE); 
  16.         sv_setting_update = (SettingView) findViewById(R.id.sv_setting_update); 
  17.         update(); 
  18.     } 
  19. /**
  20.      * 提示更新
  21.      */
  22. private void update() { 
  23. // 初始化自定义组合控件中的控件的默认值
  24. // sv_setting_update.setTitle("提示更新");
  25. // getBoolean : 从sp中获取名称是update的数据信息,defValue:如果没有找到就是defValue,缺省值
  26. if (sp.getBoolean("update", true)) { 
  27. // sv_setting_update.setDes("已打开提示更新");
  28.             sv_setting_update.setChecked(true); 
  29.         } else { 
  30. // sv_setting_update.setDes("已关闭提示更新");
  31.             sv_setting_update.setChecked(false); 
  32.         } 
  33. // 给自定义组合控件设置点击事件
  34.         sv_setting_update.setOnClickListener(new OnClickListener() { 
  35. @Override
  36. public void onClick(View v) { 
  37.                 Editor edit = sp.edit(); 
  38. // isChecked() : 获取当前checkbox的状态
  39. if (sv_setting_update.isChecked()) { 
  40. // 关闭操作
  41.                     sv_setting_update.setChecked(false); 
  42. // sv_setting_update.setDes("已关闭提示更新");
  43. // 保存状态
  44.                     edit.putBoolean("update", false); 
  45. // edit.apply();//保存到文件中的,但是仅限于9版本之上,9版本之下保存在内存
  46.                 } else { 
  47. // 打开操作
  48.                     sv_setting_update.setChecked(true); 
  49. // sv_setting_update.setDes("已打开提示更新");
  50.                     edit.putBoolean("update", true); 
  51.                 } 
  52.                 edit.commit(); 
  53.             } 
  54.         }); 
  55.     } 


3.res资源文件代码

values/attrs.xml

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <resources> 
  3.     <!-- 自定义属性 --> 
  4.     <!-- 在activity_setting.xml中使用 --> 
  5.     <declare-styleable name="com.example.settingview.ui.SettingView"> 
  6.         <attr name="title" format="string" /> <!-- format : 类型 --> 
  7.         <attr name="des_on" format="string" /> 
  8.         <attr name="des_off" format="string" /> 
  9.     </declare-styleable> 
  10. </resources> 

layout/settingview.xml

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:layout_width="match_parent"
  4.     android:layout_height="wrap_content" > 
  5.     <!-- layout_margin : 距离父控件上下左右边框的距离 --> 
  6.     <TextView 
  7.         android:id="@+id/tv_setting_title"
  8.         android:layout_width="wrap_content"
  9.         android:layout_height="wrap_content"
  10.         android:layout_margin="5dp"
  11.         android:text="提示更新"
  12.         android:textSize="18sp" /> 
  13.     <TextView 
  14.         android:id="@+id/tv_setting_des"
  15.         android:layout_width="wrap_content"
  16.         android:layout_height="wrap_content"
  17.         android:layout_below="@id/tv_setting_title"
  18.         android:layout_marginLeft="5dp"
  19.         android:text="已关闭提示更新"
  20.         android:textColor="#aa000000"
  21.         android:textSize="16sp" /> 
  22.     <!-- checkbox天生带有点击事件和获取焦点的事件  
  23.     focusable :是否可以获取焦点,false:不可以   true:可以 
  24.     clickable : 是否可以点击   false:不可以   true:可以 
  25.     --> 
  26.     <CheckBox 
  27.         android:id="@+id/cb_setting_ischecked"
  28.         android:layout_width="wrap_content"
  29.         android:layout_height="wrap_content"
  30.         android:layout_alignParentRight="true"
  31.         android:layout_centerVertical="true"
  32.         android:layout_marginRight="18dp"
  33.         android:focusable="false"
  34.         android:clickable="false"
  35.         /> 
  36.     <!-- layout_marginTop : 距离距离控件顶部的距离 --> 
  37.     <View 
  38.         android:layout_width="match_parent"
  39.         android:layout_height="0.5dp"
  40.         android:layout_below="@id/tv_setting_des"
  41.         android:layout_marginTop="5dp"
  42.         android:background="#77000000" /> 
  43. </RelativeLayout> 

layout/activity_setting.xml

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
  3.     xmlns:example="http://schemas.android.com/apk/res/com.example.settingview"
  4.     android:layout_width="match_parent"
  5.     android:layout_height="match_parent" > 
  6.     <!-- ScrollView :  只能有一个子控件,当屏幕放不下条目的时候,就会让屏幕,可以看到的时候就不会滑动--> 
  7.     <!-- 自定义属性 --> 
  8.     <!-- 系统用来声明属性用的:sdkplatformsandroid-18data esvaluesattrs.xml --> 
  9.     <com.example.settingview.SettingView 
  10.         android:id="@+id/sv_setting_update"
  11.         android:layout_width="match_parent"
  12.         android:layout_height="wrap_content"
  13.         example:des_off="已关闭提示更新"
  14.         example:des_on="已打开提示更新"
  15.         example:title="提示更新" > 
  16.     </com.example.settingview.SettingView> 
  17. </ScrollView> 

4.我们运行一下,效果如下



链接:http://pan.baidu.com/s/1jIOfR8q 密码:l9kn

原文地址:https://www.cnblogs.com/yuxuan007/p/7248269.html