码迷,mamicode.com
首页 > 移动开发 > 详细

手机卫士-03

时间:2015-04-07 11:57:14      阅读:158      评论:0      收藏:0      [点我收藏+]

标签:android开发

手机卫士-03

课1

继续引导页第四个界面的实现 GuideActivity4.class的实现 给activity_guide4.xml的 checkBox加上id TextView也加上id(因为为了改变勾上后的text状态)

activity_guide4.xml

<TextView
    style="@style/textview_title_style"
    android:text="恭喜您设置完成" 
    android:textColor="#E2DED8"/>

<CheckBox
    android:id="@+id/cb_check"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="打勾,开启防盗保护"
    android:textSize="24sp" />

<TextView
    android:id="@+id/tv_desc"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

回到GuideActivity4.class继续实现

给checkBox加上监听器(setOnCheckedChangeListener) 完善SharedpreferenceUtils里的存储方法,因为要使用到存储boolean的类型 SharedPreferencesUtil.java

public static void saveBoolean(Context context,String key ,boolean value) {
    if(sp == null)
    sp = context.getSharedPreferences(SP_NAME, 0);
    sp.edit().putBoolean(key, value).commit();
}

public static boolean getBoolean(Context context,String key,boolean defValue){
   if(sp == null)
       sp = context.getSharedPreferences(SP_NAME, 0);
   return sp.getBoolean(key, defValue);
}

上机测试下切换完成没 当点击下一步,我们就跳到手机防盗的界面,但是跳前要判断打勾没,没的话不让下一步 GuideActivity4.java

public class GuideActivity4 extends Activity {
    private TextView tv_desc;
    private Boolean isCheckedToNext;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_guide4);

        tv_desc = (TextView) findViewById(R.id.tv_desc);
        CheckBox cb_check = (CheckBox) findViewById(R.id.cb_check);

        cb_check.setOnCheckedChangeListener(new OnCheckedChangeListener() {


            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                isCheckedToNext = isChecked;
                if(isChecked){
                    tv_desc.setText("防盗保护已经开启");
                    SharedPreferencesUtil.saveBoolean(GuideActivity4.this, "protecting", isChecked);
                }else{
                    tv_desc.setText("防盗保护已经关闭");
                    SharedPreferencesUtil.saveBoolean(GuideActivity4.this, "protecting", isChecked);
                }
            }
        });
    }

    public void next(View view){
        Boolean CheckStatus = SharedPreferencesUtil.getBoolean(GuideActivity4.this, "protecting",isCheckedToNext);
        if(CheckStatus){
            System.out.println("protecting"+CheckStatus+"");
            Intent intent = new Intent(GuideActivity4.this,FindLostActivity.class);
            startActivity(intent);
            finish();
        }else{
            System.out.println("protecting"+CheckStatus+"");
            Toast.makeText(this, "请开启防盗保护", 0).show();
        }
    }
    public void pre(View view){
        Intent intent = new Intent(GuideActivity4.this,GuideActivity3.class);
        startActivity(intent);
        finish();
    }
}

技术分享

FindLostActivity(手机防盗界面),注意配清单,加上Activity节点 设计手机防盗界面activityfindlost.xml,由于在布局方面自己的能力比较薄弱,尝试自己去看着实现图来敲,敲完再对比老师的源代码 activityfindlost.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@drawable/startpage" >

    <TextView 
      style="@style/textview_title_style"
      android:text="手机防盗"
        />
    <RelativeLayout 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >
        <TextView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="安全号码"
            android:textSize="24sp"
            android:textColor="#E2DED8"
            />
        <TextView 
            android:id="@+id/tv_phone"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="xxx"
            android:textSize="24sp"
            android:textColor="#E2DED8"
            android:layout_alignParentRight="true"
            />
    </RelativeLayout>

   <View
       android:layout_width="match_parent"
       android:layout_height="1dp"
       android:background="@drawable/list_devider" />

    <RelativeLayout 
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       >
       <TextView 
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="保护是否开启"
           android:textSize="24sp"
            android:textColor="#E2DED8"
           />
    <ImageView 
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:src="@drawable/unlock"
            android:id="@+id/tv_lockChange"
           />
   </RelativeLayout>

       <View
       android:layout_width="match_parent"
       android:layout_height="1dp"
       android:background="@drawable/list_devider" />
   <Button 
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="重新进入设置向导"
       android:onClick="bt_reset"
       android:textSize="24sp"
        android:textColor="#E2DED8"
        android:background="@drawable/btn_selector"

       />
             <View
       android:layout_width="match_parent"
       android:layout_height="1dp"
       android:background="@drawable/list_devider" />
       <TextView 
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:text="功能简介"
           android:textSize="24sp"
           android:background="#88000000"
           android:textColor="#E2DED8"

           />

          <View
       android:layout_width="match_parent"
       android:layout_height="1dp"
       android:background="@drawable/list_devider" />

    <TextView 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="GPS追踪:#*location*#"
        android:drawableLeft="@android:drawable/star_big_on"
        android:textSize="22sp"
        android:textColor="#E2DED8"
        />    
    <TextView 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="播放警报音乐:#*alarm*#"
        android:drawableLeft="@android:drawable/star_big_on"
        android:textSize="22sp"
        android:textColor="#E2DED8"
        />    
    <TextView 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="远程删除数据:#*wipedata*#"
        android:drawableLeft="@android:drawable/star_big_on"
        android:textSize="22sp"
        android:textColor="#E2DED8"
        />    
    <TextView 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="远程锁屏:#*lockscreen*#"
        android:drawableLeft="@android:drawable/star_big_on"
        android:textSize="22sp"
        android:textColor="#E2DED8"
        />    


</LinearLayout>

技术分享

在样式里加上没有title的样式

技术分享

注意在xml布局里,我们要设计线,用View控件设置background 想在同一行显示文字+其他别的东西,就用相对布局把控件扩起来进行调整 在textView左边加图片可以用属性android:drawableLeft="@an....." 完成就注入到FindLostActivity.class里,改变GuideActivity4.class的下一步按钮 实现FindLostActivity.class功能 从GuideActivity4.class获取传来的sp,获取电话号码到textView里

实现小锁图片的切换

从GuideActivity4.class传来的sp里判断去判断小锁的图片切换 在onCreate里补回一个判断,为了下一次访问时的状态显示:sp里是否有finishsetup的值,实现界面的跳转:(如果用户设置了防盗界面,那么用户直接进入到防盗界面,没有就跳回GuideActivity3.class) 在FindLostActivity.class里实现menu的功能,在该界面点击按钮menu会弹出main.xml

FindLostActivity.java

package com.itheima.phonesafeguard;

public class FindLostActivity extends Activity {
    private TextView tv_phone;
    private ImageView iv_lockChange;
    private SharedPreferences sp;
    private Boolean lockStatus;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_find_lost);
        sp = getSharedPreferences("config", MODE_PRIVATE);
        sp.edit().putBoolean("setupcomplete", false).commit();
        tv_phone = (TextView) findViewById(R.id.tv_phone);
        iv_lockChange = (ImageView) findViewById(R.id.iv_lockChange);
        lockStatus = sp.getBoolean("protecting", false);
        String phone = SharedPreferencesUtil.getString(this, "phone", "");
        tv_phone.setText(phone);
        if(lockStatus){
            iv_lockChange.setImageResource(R.drawable.lock);
            sp.edit().putBoolean("setupcomplete", true).commit();
        }
    }

    public void reset(View view){
        Intent intent = new Intent(FindLostActivity.this,GuideActivity1.class);
        startActivity(intent);
    }
}

MainActivity.class

bt_ok.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                //获取密码里面的值。然后判断2次输入的值是否一样
                String et_password = et_pwd.getText().toString().trim();


                if(TextUtils.isEmpty(et_password) ){
                    return ;
                }
                String pwd = sp.getString("pwd", "");

                //如果sp里面缓存的密码和输入的密码一样的话。那么就进入防盗的引导界面
                if(et_password.equals(pwd)){
                    SharedPreferences sp = getSharedPreferences("config", MODE_PRIVATE);
                    Boolean setup = sp.getBoolean("setupcomplete", false);
                    String sim = sp.getString("sim", "");
                    if(setup && !TextUtils.isEmpty(sim)){
                        Intent intent = new Intent(MainActivity.this,FindLostActivity.class);
                        startActivity(intent);
                        dialog.dismiss();
//                      finish();
                    }else{
                        Intent intent = new Intent(MainActivity.this,GuideActivity1.class);
                        startActivity(intent);
                        dialog.dismiss();
//                      finish();
                    }

                }else{
                    Toast.makeText(MainActivity.this, "2次密码不一致", 0).show();
                }
            }
        });

strings.xml里修改些属性给main.xml使用,实现

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">PhoneSafeguard</string>
    <string name="action_settings">Settings</string>
    <string name="hello_world">Hello world!</string>
    <string name="action_changename">修改手机防盗的名称</string>

</resources>

菜单栏的实现

技术分享

在manu里的main.xml文档控制了Activity的一个菜单栏功能的布局,然而正常情况下该manu已经被屏蔽了,所以我们要使用的时候首先需要创建出来,然后再添加监听事件。

main.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/action_settings"
        android:title="@string/action_changename"/>

</menu>

加上菜单选中的方法:onOptionsItemSelected(MenuItem item),点击后弹出对话框 注意这个选中方法里的实现!

FindLostActivity.java

//菜单选中的方法
@Override
public boolean onOptionsItemSelected(MenuItem item) {

    AlertDialog.Builder builder = new Builder(this);
    builder.setTitle("设置手机防盗的名称");
    final EditText editText = new EditText(this);


    builder.setView(editText);
    builder.setPositiveButton("确定", new OnClickListener() {

        @Override
        public void onClick(DialogInterface dialog, int which) {
            String result = editText.getText().toString().trim();
            SharedPreferencesUtil.saveString(FindLostActivity.this, "changename", result);
        }
    });
    builder.show();
    return super.onOptionsItemSelected(item);
}

//创建菜单
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

回到MainActivity,在View getView里改变图标1里的新的名字

MainActivity.class

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View view = View.inflate(MainActivity.this, R.layout.item_main_gridview, null);
    TextView tv_name = (TextView) view.findViewById(R.id.tv_name);
    tv_name.setText(names[position]);
    //在这里加载图片的时候可以加一个oom的解决机制
    ImageView iv_icon = (ImageView) view.findViewById(R.id.iv_icon);
    iv_icon.setImageResource(icon[position]);

    String newname = SharedPreferencesUtil.getString(MainActivity.this, "changename", null);
    //判断是否是第0个位置。如果是修改防盗的名称
    if(position == 0){
        if(!TextUtils.isEmpty(newname) && !TextUtils.isEmpty(sim)){
            tv_name.setText(newname);
        }
    }

    return view;
}

课2

给设置了密码的sp加密 MD5加密算法写成Utils 用小demo(MD5Demo)来测试MD5 在MainActivity里加上MD5加密算法的代码 使用md5网站解密 写成Utils后在手机卫士的MainActivity里加入MD5的工具类给密码加密 测试前注意要清空sp 在应用汇!!!

package com.itheima.mobile47.utils;

public class MD5Util {

    public static String encode(String result){
        try {
            StringBuilder sb = new StringBuilder();
            //设置加密摘要
            MessageDigest digest = MessageDigest.getInstance("md5");
            byte[]  digests= digest.digest(result.getBytes());
            for(byte b : digests){
                //获取到低八位
                int number = b&0xff;
                String hex = Integer.toHexString(number);

                if(hex.length() == 1 ){
                    sb.append("0" + hex);
                }else{
                    sb.append(hex);
                }
            }
            return sb.toString();
        } catch (Exception e) {
            // TODO: handle exception
        }
        return "";
    }
}

课3

继续实现FindLostActivity.class里的重新进入设置向导的点击事件 给它加onClick属性:setEnterup和clickable属性等 为每个界面加上手势滑动识别 BaseGuideActivity新建,继承Activity,然后让每个引导界面都继承BaseGuideActivity 在BaseGuideActivity里设置手势识别器 课下总结两种手势识别器的实现方法 改造1到4个引导页的手势滑动方法 在BaseGuideActivity里的滑动过程加上动画效果

BaseGuideActivity.java

detector = new GestureDetector(this,
                new GestureDetector.SimpleOnGestureListener() {
                    /**
                     * e1 表示手指第一次触摸到屏幕 e2 表示手指第二次触摸到屏幕 velocityx 表示x轴的速度
                     * velocityY 表示y轴的速度
                     */
                    @Override
                    public boolean onFling(MotionEvent e1, MotionEvent e2,
                            float velocityX, float velocityY) {
                        // 表示上一步
                        if (e2.getRawX() - e1.getRawX() > 0) {
                            System.out.println("上一步");

                            pre();

                            BaseGuideActivity.this.overridePendingTransition(R.anim.pre_in, R.anim.pre_out);
                        }

                        if(e2.getRawX() - e1.getRawX() < 0){
                            System.out.println("表示下一步");
                            next();
                               BaseGuideActivity.this.overridePendingTransition(R.anim.next_in, R.anim.next_out);
                        }

                        return super.onFling(e1, e2, velocityX, velocityY);
                    }

                });

在res底下新建一个动画包anim

prein.xml(translate) preout.xml(translate) pre_in.xml(translate)

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="-100%p" 
    android:toXDelta="0"
    android:fromYDelta="0"
    android:toYDelta="0"
    android:duration="500"
    >

</translate>

pre_out.xml(translate)

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="0" 
    android:toXDelta="100%p"
    android:fromYDelta="0"
    android:toYDelta="0"
    android:duration="500"
    >

</translate>

设计设置中心的功能:取消更新提示 在MainActivity.class里加上case 8的操作

case 8:
    intent = new Intent(MainActivity.this,SettingCenterActivity.class);
    startActivity(intent);
    break;
}

新建SettingCenterActivity.class

SettingCenterActivity.class

public class SettingCenterActivity extends Activity {

    private CheckBox cb_state;
    private SettingView setting_view;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_setting_center);
        setting_view = (SettingView) findViewById(R.id.setting_view_update);

        //首先进来判断当前是否需要更新
        boolean result = SharedPreferencesUtil.getBoolean(SettingCenterActivity.this, "isupdate", false);

        if(result){
            setting_view.setChecked(true);
        }else{
            setting_view.setChecked(false);
        }

        setting_view.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                //判断当前的settingview里面的cb有没有被选中
                if(setting_view.isChecked()){
                    LogUtil.d(SettingCenterActivity.this, "哈哈");

                    setting_view.setChecked(false);
                    SharedPreferencesUtil.saveBoolean(SettingCenterActivity.this, "isupdate", false);

                }else{
                    LogUtil.d(SettingCenterActivity.this, "嘎嘎");
                    setting_view.setChecked(true);
                    SharedPreferencesUtil.saveBoolean(SettingCenterActivity.this, "isupdate", true);
                }

            }
        });
    }
}

配置清单

<!-- 设置中心的界面 -->
<activity
    android:name="com.itheima.mobile47.SettingCenterActivity"
    android:screenOrientation="portrait" >
</activity>

设计设置中心的布局activitysettingcenter.xml

activitysettingcenter.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:itheima="http://schemas.android.com/apk/res/com.itheima.mobile47"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        style="@style/textview_title_style"
        android:gravity="center"
        android:text="设置中心" />

    <com.itheima.mobile47.view.SettingView
        android:id="@+id/setting_view_update"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        itheima:desc="自动更新已经开启#自动更新已经关闭"
        itheima:title="自动更新设置" >
    </com.itheima.mobile47.view.SettingView>

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="@drawable/list_devider" />

    <com.itheima.mobile47.view.SettingView
        android:id="@+id/setting_view_black"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        itheima:desc="黑名单更新已经开启#黑名单更新已经关闭"
        itheima:title="黑名单设置" >
    </com.itheima.mobile47.view.SettingView>



</LinearLayout>

技术分享

我们想点击整个框就可以激活checkbox, 回到SettingCenterActivity.class去设置:获取控件 还有去掉点击checkbox点击时有篮框的样式 在查询完系统默认的checkbox的样式后,我们复制到我们的style.xml里去使用 新增btn_check.xml到drawable里,在checkbox的控件里加上该样式

btn_check.xml

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- Enabled states -->

    <item android:state_checked="true" 

          android:drawable="@drawable/btn_check_on" />
    <item android:state_checked="false" 

          android:drawable="@drawable/btn_check_off" />


</selector>

课4

继续设置中心SettingCenterActivity.class的xml布局activitysettingcenter.xml 把里面的每一个相对布局抽取出来settingView.class 继承RelativeLayout

settingView.class

public class SettingView extends RelativeLayout {

    private TextView tv_title;
    private TextView tv_desc;
    private CheckBox cb_states;
    private String[] descs;

    public SettingView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        System.out.println("----->3");
    }

    public SettingView(Context context, AttributeSet attrs) {
        super(context, attrs);
        System.out.println("----->2");
        //第一个参数是命名空间 ,第二个参数是自定义属性的名字
        String title = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.itheima.mobile47", "title");
        String desc = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.itheima.mobile47", "desc");
        View view = View.inflate(context, R.layout.ui_setting_view, null);
        this.addView(view);
        tv_title = (TextView) view.findViewById(R.id.tv_title);
        tv_desc = (TextView) view.findViewById(R.id.tv_desc);
        cb_states = (CheckBox) view.findViewById(R.id.cb_states);
        setTitle(title);
        descs = desc.split("#");
        setDescs(descs,false);
    }

   //设置描述信息
    private void setDescs(String[] descs, boolean checked) {
        if(checked){
            tv_desc.setText(descs[0]);
            tv_desc.setTextColor(Color.GREEN);
            cb_states.setChecked(true);
        }else{
            tv_desc.setText(descs[1]);
            tv_desc.setTextColor(Color.RED);
            cb_states.setChecked(false);
        }

    }

    private void setTitle(String title) {
        tv_title.setText(title);

    }

    public SettingView(Context context) {
        super(context);
        System.out.println("----->1");
    }

    public boolean isChecked() {
        // TODO Auto-generated method stub
        return cb_states.isChecked();
    }

    public void setChecked(boolean checked) {
        if(checked){
            if(tv_desc != null){
                tv_desc.setText(descs[0]);
                tv_desc.setTextColor(Color.GREEN);
                cb_states.setChecked(true);
            }


        }else{
            if(tv_desc != null){
                tv_desc.setText(descs[1]);
                tv_desc.setTextColor(Color.RED);
                cb_states.setChecked(false);
            }

        }

    }



}

继续为该布局设计一个布局xml:uisettingview.xml

uisettingview.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"
    android:orientation="vertical" >

        <TextView
            android:id="@+id/tv_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="自动更新设置"
            android:textColor="#000"
            android:textSize="24sp" />

        <TextView
            android:id="@+id/tv_desc"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/tv_title"
            android:text="自动更新已经关闭"
            android:textColor="#88000000"
            android:textSize="20sp" />

        <CheckBox
            android:id="@+id/cb_states"
            android:clickable="false"
            android:focusable="false"
            android:button="@drawable/btn_check"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" 
            android:layout_centerVertical="true"
            android:layout_alignParentRight="true"/>
</RelativeLayout>

然后引入到settingView.class里 然后在原来的activitysettingcenter.xml里把原来的Relativelayout改成自定义的控件类 activitysettingcenter.xml

<com.itheima.mobile47.view.SettingView
    android:id="@+id/setting_view_update"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    itheima:desc="自动更新已经开启#自动更新已经关闭"
    itheima:title="自动更新设置" >
</com.itheima.mobile47.view.SettingView>

测试自定义的控件类settingView.class里的构造函数初始化时调用的是哪一个。

找到之后就通过代码把uisettingview.xml注入到控件里来(并获取布局里的控件,在该类settingView.class通过方法控制显示checkbox控制的textView状态)

settingView.class

public SettingView(Context context, AttributeSet attrs) {
        super(context, attrs);
        System.out.println("----->2");
        //第一个参数是命名空间 ,第二个参数是自定义属性的名字
        String title = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.itheima.mobile47", "title");
        String desc = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.itheima.mobile47", "desc");
        View view = View.inflate(context, R.layout.ui_setting_view, null);
        this.addView(view);
        tv_title = (TextView) view.findViewById(R.id.tv_title);
        tv_desc = (TextView) view.findViewById(R.id.tv_desc);
        cb_states = (CheckBox) view.findViewById(R.id.cb_states);
        setTitle(title);
        descs = desc.split("#");
        setDescs(descs,false);
    }

在SettingCenterActivity.class里调用SettingView控件,添加点击监听事件 再把checkbox和textView联动起来,在checkBox里设置下属性(false)

SettingCenterActivity.class

setting_view.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                //判断当前的settingview里面的cb有没有被选中
                if(setting_view.isChecked()){
                    LogUtil.d(SettingCenterActivity.this, "哈哈");

                    setting_view.setChecked(false);
                    SharedPreferencesUtil.saveBoolean(SettingCenterActivity.this, "isupdate", false);

                }else{
                    LogUtil.d(SettingCenterActivity.this, "嘎嘎");
                    setting_view.setChecked(true);
                    SharedPreferencesUtil.saveBoolean(SettingCenterActivity.this, "isupdate", true);
                }

            }
        });

写一个LogUtil工具类,用来测试用:通过置换mode来控制我们在代码中嵌入的LogUtil中的日志方法,如果不想输出就在类中修改mode就行 加上开关更新提醒的功能

LogUtil.java

public class LogUtil {

    public static final boolean mode = true;

    public static void d(Object obj,String msg){
        if(mode){
            Log.d(obj.getClass().getSimpleName(), msg);
        }
    }
}

然后修改SplashActivity.class,在里面增加代码检查sp里是否有内容,从而判断是否需要获取更新的数据

SplashActivity.class

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    //获取是否更新的数据
        boolean result = SharedPreferencesUtil.getBoolean(SplashActivity.this, "isupdate", false);

        if(result){
            // 检查版本号
            checkVersion();
            // checkVersion2();
        }else{
            //防止进入主界面太快。所以睡一觉
            new Thread(){
                public void run() {
                    try {
                        Thread.sleep(2000);
                        mainUI();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                };
            }.start();


        }

继续修改小bug,在SettingCenterActivity里增加代码检查sp是否更新,是就一个状态,否就另外一个状态(text的内容)

SettingCenterActivity.java

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_setting_center);
    setting_view = (SettingView) findViewById(R.id.setting_view_update);

    //首先进来判断当前是否需要更新
    boolean result = SharedPreferencesUtil.getBoolean(SettingCenterActivity.this, "isupdate", false);

    if(result){
        setting_view.setChecked(true);
    }else{
        setting_view.setChecked(false);
    }

继续在SettingCenterACtivity.class的布局文件activitysettingcenter.xml增加自定义view,即增加条目,显示出自定义的view的方便性

课5

这里有些难,也有些重要! 我们的条目信息又自定义的控件控制数据,但是我们的数据已经写死了 修改自定义控件类,布局引用里的自定义控件加上我们自己的属性 但是这样设置不了,因为自定义控件类是包装了几个控件的, 那么我们观察下系统的源码,找出解决的办法 在value目录底下定义一个attrs.xml,然后回到activitysettingcenter.xml继续修改

attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="settingview">
        <attr name="title" format="string" />
        <attr name="desc" format="string" />
    </declare-styleable>

</resources>

然后在自定义的类中增加desc、title

SettingView.java

public SettingView(Context context, AttributeSet attrs) {
    super(context, attrs);
    System.out.println("----->2");
    //第一个参数是命名空间 ,第二个参数是自定义属性的名字
    String title = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.itheima.mobile47", "title");
    String desc = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.itheima.mobile47", "desc");
    View view = View.inflate(context, R.layout.ui_setting_view, null);
    this.addView(view);
    tv_title = (TextView) view.findViewById(R.id.tv_title);
    tv_desc = (TextView) view.findViewById(R.id.tv_desc);
    cb_states = (CheckBox) view.findViewById(R.id.cb_states);
    setTitle(title);
    descs = desc.split("#");
    setDescs(descs,false);
}

继续修改SettingView.java,在初始化构造函数中加上自定义的命名空间,获取title和desc,从而在该类型中获取到布局中传来的设置信息, 继续把写死的地方进行修改。

理解下自定义控件中的自定义属性的步骤

1、自定义命名空间 
2、自定义属性 
    1、需要在values下面新建一个attrs.xml的配置文件 
3、在自定义view的类中的两个参数的构造方法里面设置如下代码

理解不了就查看源码,看lineralayout控件的属性时怎么实现的-->sdk--->plaform--->attrs.xml里查lineralayout

(复制老师的笔记)

1 自定义命名空间

xmlns:itheima="http://schemas.android.com/apk/res/com.itheima.mobile47"

itheima               这个值可以随便定义:随便取名字
com.itheima.mobile47  这个是应用程序的包名

2 自定义属性:

在values下面新建一个attrs.xml的配置文件
<resources>

<declare-styleable name="settingview">
    <attr name="title" format="string" />
    <attr name="desc" format="string" />
</declare-styleable>

</resources>

settingview : 这个值你可以随便取

title :这个值也可以随便取 

string :就是当前值的类型

3 在自定义view的类中的两个参数的构造方法里面设置如下代码

//第一个参数是命名空间 ,第二个参数是自定义属性的名字
String title = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.itheima.mobile47", "title");

为FindLostActivity.class里的提示信息实现功能,即使用广播去控制被盗的手机,即按照规则发送信息到被盗手机(前提是卡没有)

在清单文件里新建receiver

<!-- 手机防盗的广播 -->
<receiver android:name="com.itheima.mobile47.receiver.SmsReceiver" >
    <intent-filter android:priority="1000" >
        <action android:name="android.provider.Telephony.SMS_RECEIVED" />
    </intent-filter>
</receiver>

新建一个接收短信的receiver类继承广播类SmsReceive

public class SmsReceiver extends BroadcastReceiver 配好清单文件

继续配receiver中的intent-filter

<!-- 手机防盗的广播 -->
<receiver android:name="com.itheima.mobile47.receiver.SmsReceiver" >
    <intent-filter android:priority="1000" >
        <action android:name="android.provider.Telephony.SMS_RECEIVED" />
    </intent-filter>
</receiver>

实现报警音乐,在receiver中使用MediaPlayer 把音乐放在raw文件夹里

SmsReceiver.java

@Override
public void onReceive(Context context, Intent intent) {
    System.out.println("短信来了");
    // 获取到短信的数组
    Object[] objs = (Object[]) intent.getExtras().get("pdus");
    // 获取到设备管理的Manager
    DevicePolicyManager mDPM = (DevicePolicyManager) context
            .getSystemService(Context.DEVICE_POLICY_SERVICE);

    for (Object obj : objs) {
        SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) obj);
        // 获取到短信的电话号码
        String number = smsMessage.getOriginatingAddress();
        // 获取到短信的内容
        String body = smsMessage.getMessageBody();
if (body.equals("#*alarm*#")) {
            System.out.println("报警音乐");
            MediaPlayer mediaPlayer = MediaPlayer.create(context,
                    R.raw.alarm);
            mediaPlayer.setVolume(1.0f, 1.0f);
            mediaPlayer.start();
            abortBroadcast();
        }

实现擦除数据功能:为了防止小偷偷看手机里的数据,即恢复出厂设置 即调用手机里已经实现了的功能就行(恢复出厂设置) (难) - 我们如何导入安卓源码 - sdk-->plaform--->dandroid(版本)-->sample - 在search去找擦除数据功能:建议看回视频 - 把控制擦除数据功能和锁屏功能的清单文件数据复制到清单文件中 - 在res里面新建一个xml - 写一个receiver(DeviceAdminSample)继承DeviceAdminReceiver - 继续在SmsReceiver.java里继续实现擦除数据和锁屏的功能 - 同时锁屏还要加上设置密码的功能

<!-- 系统管理的广播 -->
<receiver
    android:name="com.itheima.mobile47.receiver.DeviceAdminSample"
    android:description="@string/sample_device_admin_description"
    android:label="@string/sample_device_admin"
    android:permission="android.permission.BIND_DEVICE_ADMIN" >
    <meta-data
        android:name="android.app.device_admin"
        android:resource="@xml/device_admin_sample" />

    <intent-filter>
        <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
    </intent-filter>
</receiver>

SmsReceiver.java

@Override
public void onReceive(Context context, Intent intent) {
    System.out.println("短信来了");
    // 获取到短信的数组
    Object[] objs = (Object[]) intent.getExtras().get("pdus");
    // 获取到设备管理的Manager
    DevicePolicyManager mDPM = (DevicePolicyManager) context
            .getSystemService(Context.DEVICE_POLICY_SERVICE);

    for (Object obj : objs) {
        SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) obj);
        // 获取到短信的电话号码
        String number = smsMessage.getOriginatingAddress();
        // 获取到短信的内容
        String body = smsMessage.getMessageBody();

    if (body.equals("#*wipedata*#")) {
            System.out.println("擦除数据");
             mDPM.wipeData(DevicePolicyManager.WIPE_EXTERNAL_STORAGE);
            abortBroadcast();
        }
        if (body.equals("#*lockscreen*#")) {
            System.out.println("锁屏");
            mDPM.lockNow();
            abortBroadcast();
        }

继续实现地理位置:不能放在广播里面(广播生命周期短,而地理位置是一个耗时的操作),要放在服务里面实现,在广播里打开服务 新建包新建服务类LocationService-->清单文件配置,让SmsReceiver跳到该服务中 新建一个测试地理位置的demo,测试成功后再放到代码中

操作技巧:如何先输入方法,然后快捷键定义变量接收返回值

把代码复制到LocationService里:获取到了位置后通过短信发到目的号码中

<!-- 地理位置的服务 -->
<service android:name="com.itheima.mobile47.service.LocationService" >
</service>

SmsReceiver.java

if (body.equals("#*location*#")) {
    System.out.println("地理位置");
    Intent mLocationService = new Intent(context,LocationService.class);
    context.startService(mLocationService);
    abortBroadcast();
}

LocationService.java

public class LocationService extends Service {
    private MyLocationListener listener;

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void onCreate() {
        // TODO Auto-generated method stub
        super.onCreate();
        LocationManager lm = (LocationManager) getSystemService(LOCATION_SERVICE);
        // 第一个是请求的provider
        // 第二个参数表示最短时间
        // 第三个参数表示最短的距离
        // 第四个参数表示监听

        listener = new MyLocationListener();
        // 设置查询的条件
        Criteria criteria = new Criteria();
        // 设置精确的
        criteria.setAccuracy(Criteria.ACCURACY_FINE);
        // 设置允许产生开销
        criteria.setCostAllowed(true);
        //获取到最好的provider
        String provider = lm.getBestProvider(criteria, true);

        lm.requestLocationUpdates(provider, 0, 0, listener);
    }

    private class MyLocationListener implements LocationListener {

        @Override
        public void onLocationChanged(Location location) {

            StringBuilder sb = new StringBuilder();

            // 获取到经度
            double longitude = location.getLongitude();
            // 获取到纬度
            double latitude = location.getLatitude();

            System.out.println("经度--->" + longitude);
            System.out.println("纬度--->" + latitude);
            sb.append("jingdu" + longitude + "" + "weidu" + latitude);

            String phone = SharedPreferencesUtil.getString(LocationService.this, "phone", "");

            SmsManager.getDefault().sendTextMessage(phone, null, sb.toString(), null, null);


        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onProviderEnabled(String provider) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onProviderDisabled(String provider) {
            // TODO Auto-generated method stub

        }

    }

    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
    }

}

技术分享

技术总结

strings.xml里修改些属性给main.xml使用,实现

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">PhoneSafeguard</string>
    <string name="action_settings">Settings</string>
    <string name="hello_world">Hello world!</string>
    <string name="action_changename">修改手机防盗的名称</string>

</resources>

菜单栏的实现 

技术分享

在manu里的main.xml文档控制了Activity的一个菜单栏功能的布局,然而正常情况下该manu已经被屏蔽了,所以我们要使用的时候首先需要创建出来,然后再添加监听事件。

main.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/action_settings"
        android:title="@string/action_changename"/>

</menu>

加上菜单选中的方法:onOptionsItemSelected(MenuItem item),点击后弹出对话框 注意这个选中方法里的实现!

FindLostActivity.java

//菜单选中的方法
@Override
public boolean onOptionsItemSelected(MenuItem item) {

    AlertDialog.Builder builder = new Builder(this);
    builder.setTitle("设置手机防盗的名称");
    final EditText editText = new EditText(this);


    builder.setView(editText);
    builder.setPositiveButton("确定", new OnClickListener() {

        @Override
        public void onClick(DialogInterface dialog, int which) {
            String result = editText.getText().toString().trim();
            SharedPreferencesUtil.saveString(FindLostActivity.this, "changename", result);
        }
    });
    builder.show();
    return super.onOptionsItemSelected(item);
}

//创建菜单
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

在BaseGuideActivity里的滑动过程加上动画效果

BaseGuideActivity.java

detector = new GestureDetector(this,
                new GestureDetector.SimpleOnGestureListener() {
                    /**
                     * e1 表示手指第一次触摸到屏幕 e2 表示手指第二次触摸到屏幕 velocityx 表示x轴的速度
                     * velocityY 表示y轴的速度
                     */
                    @Override
                    public boolean onFling(MotionEvent e1, MotionEvent e2,
                            float velocityX, float velocityY) {
                        // 表示上一步
                        if (e2.getRawX() - e1.getRawX() > 0) {
                            System.out.println("上一步");

                            pre();

                            BaseGuideActivity.this.overridePendingTransition(R.anim.pre_in, R.anim.pre_out);
                        }

                        if(e2.getRawX() - e1.getRawX() < 0){
                            System.out.println("表示下一步");
                            next();
                            BaseGuideActivity.this.overridePendingTransition(R.anim.next_in, R.anim.next_out);
                        }

                        return super.onFling(e1, e2, velocityX, velocityY);
                    }

                });

在res底下新建一个动画包anim prein.xml(translate) preout.xml(translate) pre_in.xml(translate)

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="-100%p" 
    android:toXDelta="0"
    android:fromYDelta="0"
    android:toYDelta="0"
    android:duration="500"
    >

</translate>

pre_out.xml(translate)

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="0" 
    android:toXDelta="100%p"
    android:fromYDelta="0"
    android:toYDelta="0"
    android:duration="500"
    >

</translate>

选择器的实现

delet_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
     <item android:state_pressed="true"
          android:drawable="@drawable/ic_delete_btn_focused" /> <!-- pressed -->
    <item android:state_focused="true"
          android:drawable="@drawable/ic_delete_btn_focused" /> <!-- focused -->

    <item android:drawable="@drawable/ic_delete_btn" /> <!-- default -->

</selector>

itemcallsafe.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"
    >

    <ImageView 
        android:id="@+id/iv_delete"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/delet_selector"
        android:layout_centerVertical="true"
        android:layout_alignParentRight="true"
        android:layout_marginRight="10dp"
        />

</RelativeLayout>

自定义控件的实现(难点)

继续设置中心SettingCenterActivity.class的xml布局activitysettingcenter.xml 把里面的每一个相对布局抽取出来settingView.class 继承RelativeLayout

attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="settingview">
        <attr name="title" format="string" />
        <attr name="desc" format="string" />
    </declare-styleable>

</resources>

settingView.class

public class SettingView extends RelativeLayout {

    private TextView tv_title;
    private TextView tv_desc;
    private CheckBox cb_states;
    private String[] descs;

    public SettingView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        System.out.println("----->3");
    }

    public SettingView(Context context, AttributeSet attrs) {
        super(context, attrs);
        System.out.println("----->2");
        //第一个参数是命名空间 ,第二个参数是自定义属性的名字
        String title = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.itheima.mobile47", "title");
        String desc = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.itheima.mobile47", "desc");
        View view = View.inflate(context, R.layout.ui_setting_view, null);
        this.addView(view);
        tv_title = (TextView) view.findViewById(R.id.tv_title);
        tv_desc = (TextView) view.findViewById(R.id.tv_desc);
        cb_states = (CheckBox) view.findViewById(R.id.cb_states);
        setTitle(title);
        descs = desc.split("#");
        setDescs(descs,false);
    }

   //设置描述信息
    private void setDescs(String[] descs, boolean checked) {
        if(checked){
            tv_desc.setText(descs[0]);
            tv_desc.setTextColor(Color.GREEN);
            cb_states.setChecked(true);
        }else{
            tv_desc.setText(descs[1]);
            tv_desc.setTextColor(Color.RED);
            cb_states.setChecked(false);
        }

    }

    private void setTitle(String title) {
        tv_title.setText(title);

    }

    public SettingView(Context context) {
        super(context);
        System.out.println("----->1");
    }

    public boolean isChecked() {
        // TODO Auto-generated method stub
        return cb_states.isChecked();
    }

    public void setChecked(boolean checked) {
        if(checked){
            if(tv_desc != null){
                tv_desc.setText(descs[0]);
                tv_desc.setTextColor(Color.GREEN);
                cb_states.setChecked(true);
            }


        }else{
            if(tv_desc != null){
                tv_desc.setText(descs[1]);
                tv_desc.setTextColor(Color.RED);
                cb_states.setChecked(false);
            }

        }

    }



}

继续为该布局设计一个布局xml:uisettingview.xml

uisettingview.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"
    android:orientation="vertical" >

        <TextView
            android:id="@+id/tv_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="自动更新设置"
            android:textColor="#000"
            android:textSize="24sp" />

        <TextView
            android:id="@+id/tv_desc"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/tv_title"
            android:text="自动更新已经关闭"
            android:textColor="#88000000"
            android:textSize="20sp" />

        <CheckBox
            android:id="@+id/cb_states"
            android:clickable="false"
            android:focusable="false"
            android:button="@drawable/btn_check"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" 
            android:layout_centerVertical="true"
            android:layout_alignParentRight="true"/>
</RelativeLayout>

然后引入到settingView.class里 然后在原来的activitysettingcenter.xml里把原来的Relativelayout改成自定义的控件类 activitysettingcenter.xml

<com.itheima.mobile47.view.SettingView
    android:id="@+id/setting_view_update"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    itheima:desc="自动更新已经开启#自动更新已经关闭"
    itheima:title="自动更新设置" >
</com.itheima.mobile47.view.SettingView>

测试自定义的控件类settingView.class里的构造函数初始化时调用的是哪一个。

找到之后就通过代码把uisettingview.xml注入到控件里来(并获取布局里的控件,在该类settingView.class通过方法控制显示checkbox控制的textView状态)

settingView.class

public SettingView(Context context, AttributeSet attrs) {
        super(context, attrs);
        System.out.println("----->2");
        //第一个参数是命名空间 ,第二个参数是自定义属性的名字
        String title = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.itheima.mobile47", "title");
        String desc = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.itheima.mobile47", "desc");
        View view = View.inflate(context, R.layout.ui_setting_view, null);
        this.addView(view);
        tv_title = (TextView) view.findViewById(R.id.tv_title);
        tv_desc = (TextView) view.findViewById(R.id.tv_desc);
        cb_states = (CheckBox) view.findViewById(R.id.cb_states);
        setTitle(title);
        descs = desc.split("#");
        setDescs(descs,false);
    }

在SettingCenterActivity.class里调用SettingView控件,添加点击监听事件 再把checkbox和textView联动起来,在checkBox里设置下属性(false)

SettingCenterActivity.class

setting_view.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                //判断当前的settingview里面的cb有没有被选中
                if(setting_view.isChecked()){
                    LogUtil.d(SettingCenterActivity.this, "哈哈");

                    setting_view.setChecked(false);
                    SharedPreferencesUtil.saveBoolean(SettingCenterActivity.this, "isupdate", false);

                }else{
                    LogUtil.d(SettingCenterActivity.this, "嘎嘎");
                    setting_view.setChecked(true);
                    SharedPreferencesUtil.saveBoolean(SettingCenterActivity.this, "isupdate", true);
                }

            }
        });

继续修改小bug,在SettingCenterActivity里增加代码检查sp是否更新,是就一个状态,否就另外一个状态(text的内容)

SettingCenterActivity.java

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_setting_center);
    setting_view = (SettingView) findViewById(R.id.setting_view_update);

    //首先进来判断当前是否需要更新
    boolean result = SharedPreferencesUtil.getBoolean(SettingCenterActivity.this, "isupdate", false);

    if(result){
        setting_view.setChecked(true);
    }else{
        setting_view.setChecked(false);
    }

继续在SettingCenterACtivity.class的布局文件activitysettingcenter.xml增加自定义view,即增加条目,显示出自定义的view的方便性

这里有些难,也有些重要!

我们的条目信息又自定义的控件控制数据,但是我们的数据已经写死了 修改自定义控件类,布局引用里的自定义控件加上我们自己的属性 但是这样设置不了,因为自定义控件类是包装了几个控件的, 那么我们观察下系统的源码,找出解决的办法 在value目录底下定义一个attrs.xml,然后回到activitysettingcenter.xml继续修改 attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="settingview">
        <attr name="title" format="string" />
        <attr name="desc" format="string" />
    </declare-styleable>

</resources>

然后在自定义的类中增加desc、title

SettingView.java

public SettingView(Context context, AttributeSet attrs) {
    super(context, attrs);
    System.out.println("----->2");
    //第一个参数是命名空间 ,第二个参数是自定义属性的名字
    String title = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.itheima.mobile47", "title");
    String desc = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.itheima.mobile47", "desc");
    View view = View.inflate(context, R.layout.ui_setting_view, null);
    this.addView(view);
    tv_title = (TextView) view.findViewById(R.id.tv_title);
    tv_desc = (TextView) view.findViewById(R.id.tv_desc);
    cb_states = (CheckBox) view.findViewById(R.id.cb_states);
    setTitle(title);
    descs = desc.split("#");
    setDescs(descs,false);
}

继续修改SettingView.java,在初始化构造函数中加上自定义的命名空间,获取title和desc,从而在该类型中获取到布局中传来的设置信息, 继续把写死的地方进行修改。

理解下自定义控件中的自定义属性的步骤 1、自定义命名空间 2、自定义属性 1、需要在values下面新建一个attrs.xml的配置文件 3、在自定义view的类中的两个参数的构造方法里面设置如下代码

理解不了就查看源码,看lineralayout控件的属性时怎么实现的-->sdk--->plaform--->attrs.xml里查lineralayout

(复制老师的笔记)

1 自定义命名空间(这个非常重要,如果不加,itheima就无法和attrs.xml里的item关联起来:即下面的实例itheima:desc="自动更新已经开启#自动更新已经关闭"无效)

xmlns:itheima="http://schemas.android.com/apk/res/com.itheima.mobile47"

itheima               这个值可以随便定义:随便取名字
com.itheima.mobile47  这个是应用程序的包名

2 自定义属性:

在values下面新建一个attrs.xml的配置文件
<resources>

    <declare-styleable name="settingview">
    <attr name="title" format="string" />
    <attr name="desc" format="string" />
    </declare-styleable>

</resources>

  settingview : 这个值你可以随便取

  title :这个值也可以随便取 

  string :就是当前值的类型

3 在自定义view的类中的两个参数的构造方法里面设置如下代码 //第一个参数是命名空间 ,第二个参数是自定义属性的名字 String title = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.itheima.mobile47", "title");

定义完之后的直接展示

<com.itheima.mobile47.view.SettingView
    android:id="@+id/setting_view_update"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    itheima:desc="自动更新已经开启#自动更新已经关闭"
    itheima:title="自动更新设置" >
</com.itheima.mobile47.view.SettingView>

技术分享

手机卫士-03

标签:android开发

原文地址:http://blog.csdn.net/faith_yee/article/details/44917935

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!