• 手机安全卫士——在设置中心 自定义view和自定义属性


    自定义组合控件
    1. 自定义一个View, 继承ViewGroup,比如RelativeLayout,此文中是SettingItemView
    2. 编写组合控件的布局文件,在自定义的View中加载
                // 将自定义好的布局文件设置给当前的SettingItemView
            View.inflate(getContext(), R.layout.view_setting_item, this);
    3. 自定义属性

          删除代码中对文本的动态设置,改为在布局文件中设置

          在布局文件中增加新的命名空间

          创建attrs.xml,定义相关属性

          读取自定义的值,更新相关内容

    activity_setting.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:mobilesafe="http://schemas.android.com/apk/res/com.mxn.mobilesafe"//自定义命名空间。。。在布局文件中增加新的命名空间
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
    
        <TextView
            
            style="@style/TitleStyle"
            android:text="设置中心" />
    
        <com.mxn.mobilesafe.view.SettingItemView
            android:id="@+id/siv_update"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"

    //自定义属性,不用android默认的属性
    //从命名空间中找
    mobilesafe:title
    ="自动更新设置" mobilesafe:desc_on="自动更新已开启" mobilesafe:desc_off="自动更新已关闭" > </com.mxn.mobilesafe.view.SettingItemView> <com.mxn.mobilesafe.view.SettingItemView android:id="@+id/siv_address" android:layout_width="match_parent" android:layout_height="wrap_content" mobilesafe:title="归属地显示设置" mobilesafe:desc_on="归属地显示已开启" mobilesafe:desc_off="归属地显示已关闭" > </com.mxn.mobilesafe.view.SettingItemView> <com.mxn.mobilesafe.view.SettingClickView android:id="@+id/scv_address_style" android:layout_width="match_parent" android:layout_height="wrap_content" > </com.mxn.mobilesafe.view.SettingClickView> <com.mxn.mobilesafe.view.SettingItemView android:id="@+id/siv_watchdog" android:layout_width="match_parent" android:layout_height="wrap_content" mobilesafe:title="看门狗设置" mobilesafe:desc_on="看门狗已开启" mobilesafe:desc_off="看门狗已关闭" > </com.mxn.mobilesafe.view.SettingItemView> </LinearLayout>
    自定义属性 : attrs.xml。。创建attrs.xml,定义相关属性
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <declare-styleable name="SettingItemView">
            <attr name="title"  format="string"></attr>
            <attr name="desc_on"  format="string"></attr>
            <attr name="desc_off"  format="string"></attr>
                    
        </declare-styleable>
        
    </resources>
     
    SettingItemView.java
    /*
     * 设置中心的自定义控件,自定义View
     */
    public class SettingItemView extends RelativeLayout {
        TextView tvTitle;
        TextView tvDesc;
        CheckBox cbStatus;
        private String mtitle;
        private String mdescon;
        private String mdescoff;
    String namespace
    = "http://schemas.android.com/apk/res/com.mxn.mobilesafe";//命名空间 public SettingItemView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); // TODO Auto-generated constructor stub initView(); } public SettingItemView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); // TODO Auto-generated constructor stub initView(); // int attributeCount = attrs.getAttributeCount(); // for(int i=0;i<attributeCount;i++){ // String attrsname = attrs.getAttributeName(i); // String attrvalue = attrs.getAttributeValue(i); // System.out.println(attrsname+"="+attrvalue); // // } } public SettingItemView(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub
    // 读取自定义的值,更新相关内容
    //根据属性名称获取属性的值 mtitle = attrs.getAttributeValue(namespace , "title"); mdescon = attrs.getAttributeValue(namespace , "desc_on"); mdescoff = attrs.getAttributeValue(namespace , "desc_off");
    initView();
    }
    public SettingItemView(Context context) { super(context); // TODO Auto-generated constructor stub initView(); } // 初始化布局 private void initView() { // 把自定义好的布局设置给当前的SettingItemView View.inflate(getContext(), R.layout.view_setting_item, this);// this表示把view_setting_item布局塞给RelativeLayout tvTitle = (TextView) findViewById(R.id.tv_title); tvDesc = (TextView) findViewById(R.id.tv_desc); cbStatus = (CheckBox) findViewById(R.id.cb_status); setTitle(mtitle); } public void setTitle(String title) { tvTitle.setText(title); } public void setDesc(String desc) { tvDesc.setText(desc); } // 判断当前的勾选状态并返回 public boolean isChecked() { return cbStatus.isChecked(); } public void setChecked(boolean check){ cbStatus.setChecked(check); //根据选择的状态更新文本描述 if(check){ setDesc(mdescon); }else{ setDesc(mdescoff); } } }
    view_setting_item.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="80dp" 
            android:padding="10dp">
    
            <TextView
                android:id="@+id/tv_title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
               
                android:textColor="@color/black"
                android:textSize="20sp"/>
            <TextView
                android:id="@+id/tv_desc"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="5dp"
                
                android:textColor="#a000"
                android:layout_below="@id/tv_title"
                android:textSize="15sp"/>
            <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"//不能获取焦点 android:focusableInTouchMode="false" /> <View android:layout_width="match_parent" android:layout_height="0.2dp" android:background="#a000" android:layout_alignParentBottom="true" /> </RelativeLayout>
    SettingClickView.java
    /*
     * 设置中心的自定义控件,自定义View
     */
    public class SettingClickView extends RelativeLayout {
        private TextView tvTitle;
        private TextView tvDesc;
    
        public SettingClickView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            initView();
        }
    
        public SettingClickView(Context context, AttributeSet attrs) {
            super(context, attrs);
            initView();
        }
    
        public SettingClickView(Context context) {
            super(context);
            initView();
        }
    
        /**
         * 初始化布局
         */
        private void initView() {
            // 将自定义好的布局文件设置给当前的SettingClickView
            View.inflate(getContext(), R.layout.view_setting_click, this);
            tvTitle = (TextView) findViewById(R.id.tv_title);
            tvDesc = (TextView) findViewById(R.id.tv_desc);
        }
    
        public void setTitle(String title) {
            tvTitle.setText(title);
        }
    
        public void setDesc(String desc) {
            tvDesc.setText(desc);
        }
        
        
    }
    view_setting_click.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="80dp" 
            android:padding="10dp">
    
            <TextView
                android:id="@+id/tv_title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
               
                android:textColor="@color/black"
                android:textSize="20sp"/>
            <TextView
                android:id="@+id/tv_desc"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="5dp"
                
                android:textColor="#a000"
                android:layout_below="@id/tv_title"
                android:textSize="15sp"/>
            <ImageView 
                android:src="@drawable/jiantou1_pressed"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:layout_centerVertical="true"
                android:id="@+id/iv_jt"
                />
            <View
                android:layout_width="match_parent"
                android:layout_height="0.2dp"
                android:background="#a000"
                android:layout_alignParentBottom="true"
                />
        </RelativeLayout>

    运行界面:

    SettingActivity.java

    /**
     * 设置中心
     * 
     * @author mxn
     * 
     */
    public class SettingActivity extends Activity {
    
        private SettingItemView sivUpdate;// 设置自动更新
        private SettingItemView sivAddress;// 设置归属地
        private SettingClickView scvAddressStyle;// 修改风格
        private SettingClickView scvAddressLocation;// 修改归属地位置
        private SharedPreferences mPref;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_setting);
    
            mPref = getSharedPreferences("config", MODE_PRIVATE);
            //MODE_PRIVATE访问权限
            initUpdateView();
            initAddressView();
            initAddressStyle();           
        }
    
        /**
         * 初始化自动更新开关
         */
        private void initUpdateView() {
            sivUpdate = (SettingItemView) findViewById(R.id.siv_update);
            // sivUpdate.setTitle("自动更新设置");
            //默认设置的开启,用户进入之后
            boolean autoUpdate = mPref.getBoolean("auto_update", true);
    
            if (autoUpdate) {
                // sivUpdate.setDesc("自动更新已开启");
                sivUpdate.setChecked(true);
            } else {
                // sivUpdate.setDesc("自动更新已关闭");
                sivUpdate.setChecked(false);
            }
    
            sivUpdate.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    // 判断当前的勾选状态
                    if (sivUpdate.isChecked()) {
                        // 设置不勾选
                        sivUpdate.setChecked(false);
                        // sivUpdate.setDesc("自动更新已关闭");
                        // 更新sp
                        mPref.edit().putBoolean("auto_update", false).commit();
                    } else {
                        sivUpdate.setChecked(true);
                        // sivUpdate.setDesc("自动更新已开启");
                        // 更新sp
                        mPref.edit().putBoolean("auto_update", true).commit();
                    }
                }
            });
        }
    
        /**
         * 初始化归属地开关显示
         */
        private void initAddressView() {
            sivAddress = (SettingItemView) findViewById(R.id.siv_address);
    
            // 根据归属地服务是否运行来更新checkbox
            boolean serviceRunning = ServiceStatusUtils.isServiceRunning(this,
                    "com.itheima52.mobilesafe.service.AddressService");
    
            if (serviceRunning) {
                sivAddress.setChecked(true);
            } else {
                sivAddress.setChecked(false);
            }
    
            sivAddress.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    if (sivAddress.isChecked()) {
                        sivAddress.setChecked(false);
                        stopService(new Intent(SettingActivity.this,
                                AddressService.class));// 停止归属地服务
                    } else {
                        sivAddress.setChecked(true);
                        startService(new Intent(SettingActivity.this,
                                AddressService.class));// 开启归属地服务
                    }
                }
            });
        }
    
        final String[] items = new String[] { "半透明", "活力橙", "卫士蓝", "金属灰", "苹果绿" };
    
        /**
         * 修改归属地提示框显示风格
         */
        private void initAddressStyle() {
            scvAddressStyle = (SettingClickView) findViewById(R.id.scv_address_style);
    
            scvAddressStyle.setTitle("归属地提示框风格");
    
            int style = mPref.getInt("address_style", 0);// 读取保存的style
            scvAddressStyle.setDesc(items[style]);
    
            scvAddressStyle.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    showSingleChooseDailog();
                }
            });
        }
    
        /**
         * 弹出选择风格的单选框
         */
        protected void showSingleChooseDailog() {
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            // builder.setIcon(R.drawable.ic_launcher);
            builder.setTitle("归属地提示框风格");
    
            int style = mPref.getInt("address_style", 0);// 读取保存的style
    
            builder.setSingleChoiceItems(items, style,
                    new DialogInterface.OnClickListener() {
    
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            mPref.edit().putInt("address_style", which).commit();// 保存选择的风格
                            dialog.dismiss();// 让dialog消失
    
                            scvAddressStyle.setDesc(items[which]);// 更新组合控件的描述信息
                        }
                    });
    
            builder.setNegativeButton("取消", null);
            builder.show();
        }
    
    }
  • 相关阅读:
    记录java设计模式中适配器模式和装饰器模式和代理模式的区别
    excel工具类记录
    docker搭建图床 chevereto 非常方便
    docker 安装mysql
    rabbitmq学习之路(八)
    理解js中的作用域,作用域链以及闭包
    浏览器解析js的顺序
    javacript 组合使用构造函数模式和原型模式
    js垃圾回收机制与深拷贝和浅拷贝
    ES6 变量的解构赋值
  • 原文地址:https://www.cnblogs.com/mengxiao/p/6365892.html
Copyright © 2020-2023  润新知