手机安全卫士第二天

手机安全卫士第二天实现的功能:

1.自定义View和自定义属性让其实现了点击事件。

2.两个弹窗一个用来设置密码一个用来进行密码效验,密码进行了MD5加密处理。

3.手机防盗功能界面的实现(其中包括了状态选择器,9-Patch图片处理,跳转的动画)。

4.shape形状的使用。


首先进行了自定义View和自定义属性功能的实现

1.开始用settingItemView继承了一个View Relativelayout,然后实现了其构造方法的方法,在每个构造方法里进行初始化操作,然后在XML文件里自定义了属性,然后在自定义中settingItemView进行属性的初始化,代码如下。

<span style="font-size:14px;">/**
 * 自定义的组合控件
 * Created by Administrator on 2016/4/26.
 */
public class SettingItemView extends RelativeLayout {
    private static final String NAMESPACE = "http://schemas.android.com/apk/com.daizhihao.mobilesafe";
    private TextView tvTitle;
    private TextView tvDesc;
    private CheckBox cbStatus;
    private String mTitle;
    private String mDescOn;
    private String mDescOff;

    // 用代码new对象时,走此方法
    public SettingItemView(Context context) {
        super(context);
        initView();
    }

    // 有属性时走此方法
    public SettingItemView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // 根据属性名称,获取属性的值
        mTitle = attrs.getAttributeValue(NAMESPACE,"tv_title");
        mDescOn = attrs.getAttributeValue(NAMESPACE,"desc_on");
        mDescOff = attrs.getAttributeValue(NAMESPACE,"desc_off");
        initView();

    }

    // 有style样式的话会走此方法
    public SettingItemView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }

    /**
     * 初始化布局
     */
    private void initView() {
        // 将自定义好的布局文件设置给当前的SettingItemView
        View.inflate(getContext(), R.layout.view_setting, this);
        tvTitle = (TextView) findViewById(R.id.tv_title);
        tvDesc = (TextView) findViewById(R.id.tv_desc);
        cbStatus = (CheckBox) findViewById(R.id.cb_status);

        setTitle(mTitle);
    }</span>
2.然后在另外一个布局里面使用该自定义的View,使用方法是在布局里面导入该路径,要使用自定义的属性,需要先设置一个xmlns的名字然后加上路径,代码如下。

<span style="font-size:14px;"> xmlns:hysy="http://schemas.android.com/apk/com.daizhihao.mobilesafe"
<com.daizhihao.mobilesafe.view.SettingItemView
        android:id="@+id/siv_update"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        hysy:desc_off="自动更新已关闭"
        hysy:desc_on="自动更新已开启"
        hysy:tv_title="自动更新设置"
        ></span>

3.最后在该自定义控件和这个界面进行一些简单的交互。

  <span style="font-size:14px;">sivUpdate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 判断当前的勾选状态
                if (sivUpdate.isChecked()) {
                    // 设置不勾选
                    sivUpdate.setChecked(false);
                    // 更新sp
                    mPref.edit().putBoolean("auto_update", false).commit();
                } else {
                    sivUpdate.setChecked(true);
                    // 更新sp
                    mPref.edit().putBoolean("auto_update", true).commit();
                }
            }
        });</span>

然后实现了两个自定义弹窗(需要先自定义一个布局然后设置到弹窗中),分别用来,用户第一次点击用来保存用户输入的密码,第二次点击用来效验用户输入的密码是否正确,如果正确则进行下面的操作,如果不正确提示用户错误。

1.首先判断用户是第一次点击还是第几次点击,然后根据用户点击实现相对的功能。

<span style="font-size:14px;"> /**
     * 显示密码弹窗
     */
    private void showPasswordDialog() {
        // 判断是否设置密码
        String savedPassword = mPref.getString("password", null);
        if (!TextUtils.isEmpty(savedPassword)) {
            //已经输入过密码
            showPasswordinputDialog();
        } else {
            //若没有是设置密码则跳转到输入密码
            showPasswordsetDialog();
        }
    }</span>
2.判断之后弹出对应的弹窗,然后根据用户的输入的密码,进行是否让用户进入手机防盗界面。第一次先让用户保存一次密码,第二次用户必须输入第一次保存的密码才算正确输入。

  <span style="font-size:14px;"> /**
     * 输入密码弹框
     */
    private void showPasswordinputDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        final AlertDialog alertDialog = builder.create();
        View view = View.inflate(this, R.layout.dailog_input_password, null);
        alertDialog.setView(view, 0, 0, 0, 0);//为对话框设置自定义布局并设置4边留白保证在2.x的版本上运行没问题
        Button btn_OK = (Button) view.findViewById(R.id.btn_ok);
        Button btn_cancel = (Button) view.findViewById(R.id.btn_cancel);
        final EditText ev_password = (EditText) view.findViewById(R.id.et_password);
        btn_OK.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String password = ev_password.getText().toString();
                String savedPassword = mPref.getString("password", null);
                //判断String是否为空字符串
               if (!TextUtils.isEmpty(password)){
                   if (MD5Utils.encode(password).equals(savedPassword)){
                       startActivity(new Intent(HomeActivity.this,LostFindActivity.class));
                       alertDialog.dismiss();
                   }else {
                       Toast.makeText(HomeActivity.this, "密码错误", Toast.LENGTH_SHORT).show();
                   }
               }else {
                   Toast.makeText(HomeActivity.this, "输入框不能为空", Toast.LENGTH_SHORT).show();
               }
            }
        });
        btn_cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                alertDialog.dismiss();//隐藏对话框
            }
        });
        alertDialog.show();
    }

    /**
     * 弹出设置密码对话框
     */
    private void showPasswordsetDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        final AlertDialog alertDialog = builder.create();
        View view = View.inflate(this, R.layout.dailog_set_password, null);
        alertDialog.setView(view, 0, 0, 0, 0);//为对话框设置自定义布局并设置4边留白保证在2.x的版本上运行没问题
        Button btn_OK = (Button) view.findViewById(R.id.btn_ok);
        Button btn_cancel = (Button) view.findViewById(R.id.btn_cancel);
        final EditText ev_password = (EditText) view.findViewById(R.id.et_password);
        final EditText ev_passwordConfirm = (EditText) view.findViewById(R.id.et_password_confirm);
        btn_OK.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String password = ev_password.getText().toString();
                String passwordConfirm = ev_passwordConfirm.getText().toString();
                //判断String是否为空字符串
                if (!TextUtils.isEmpty(password) && !TextUtils.isEmpty(passwordConfirm)) {
                    if (password.equals(passwordConfirm)) {
                        mPref.edit().putString("password", MD5Utils.encode(password)).commit();
                        startActivity(new Intent(HomeActivity.this, LostFindActivity.class));
                        alertDialog.dismiss();
                    } else {
                        Toast.makeText(HomeActivity.this, "两次密码输入不一致密码输入", Toast.LENGTH_SHORT).show();
                    }
                } else {
                    Toast.makeText(HomeActivity.this, "输入框不能为空", Toast.LENGTH_SHORT).show();
                }
            }
        });
        btn_cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                alertDialog.dismiss();//隐藏对话框
            }
        });
        alertDialog.show();
    }</span>
3.密码保存,效验都采用的MD5加密,如果嫌MD5不够安全,可以对MD5进行加盐处理(对用户的密码加一串字符串再进行MD5加密)。

<span style="font-size:14px;">public class MD5Utils {

	/**
	 * md5加密
	 * 
	 * @param password
	 * @return
	 */
	public static String encode(String password) {
		try {
			MessageDigest instance = MessageDigest.getInstance("MD5");// 获取MD5算法对象
			byte[] digest = instance.digest(password.getBytes());// 对字符串加密,返回字节数组

			StringBuffer sb = new StringBuffer();
			for (byte b : digest) {
				int i = b & 0xff;// 获取字节的低八位有效值
				String hexString = Integer.toHexString(i);// 将整数转为16进制

				if (hexString.length() < 2) {
					hexString = "0" + hexString;// 如果是1位的话,补0
				}

				sb.append(hexString);
			}

			return sb.toString();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			// 没有该算法时,抛出异常, 不会走到这里
		}

		return "";
	}
}</span>

用户输入了正确的密码之后就应该是跳转到手机防盗的向导页面,在手机向导页面最主要的是状态选择器,9-Patch,向导页面的开发。

1.状态选择器的定义,在deawable里面新建一个XML文件,然后对 android:state_pressed="true"状态(按下的状态),android:state_focused="true"状态(获得焦点的状态)item android:drawable="@drawable/function_greenbutton_normal"状态(默认的状态)分别进行选择对应的图片

<span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?>
	<selector xmlns:android="http://schemas.android.com/apk/res/android">
	
	    <item android:drawable="@drawable/function_greenbutton_pressed" android:state_pressed="true"/>//按下的图片
	    <!-- pressed -->
	    <item android:drawable="@drawable/function_greenbutton_pressed" android:state_focused="true"/>//获取焦点的图片
	    <!-- focused -->
	    <item android:drawable="@drawable/function_greenbutton_normal"/>
	    <!-- default -->//默认图片
	
	</selector>

	 <Button
            android:background="@drawable/btn_green_selector"
       />//将选择器设置给Button</span>


2.9-Patch图片的制作
> 通过黑色边线来描述图片的拉伸情况和填充文字的方式
> 上边线表示图片水平拉伸, 左边线表示垂直拉伸
> 右边线表示垂直填充区域, 下边线表示水平填充区域


最后是Shape的介绍,自定义一个形状然后给某一个空间设置成北京即可使用
<span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
    <!-- 角度 -->
    <corners android:radius="5dp" />
    <!--
 	   渐变
    <gradient
        android:centerColor="#fff"
        android:endColor="#0f0"
        android:startColor="#f00" />
    -->
    <!-- 纯色 -->
    <solid android:color="#9000" />
    <!-- 边框 
    <stroke 
        android:width="1dp"
        android:color="#000"
        android:dashWidth="5dp"
        android:dashGap="3dp"
        />
        -->
</shape></span>








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值