【0063】【项目实战】-【手机安全卫士】-【2】

1. 增加淡入淡出的透明动画效果的添加

1.1 异常的报错

【说明】因为没有开启服务器,服务器上的数据无法读取,因此会出现读取异常;

1.2 初始化动画

1.3 动画对当前控件的选择

【说明】选择动画的控件:就是当前的空间的相对布局;

1.4 源码

1.5 实际的效果:逐渐变深,3秒钟

2.Home的主界面的布局

2.1 界面效果

【布局分析】

【1】包含标题:功能列表

【2】滚动的字幕

【3】九宫格的点击按钮

2.2 标题布局的显示

2.3 样式的抽取

2.4 滚动文字的显示

2.4.1 添加省略点的位置属性

【默认值】默认是在尾部

2.4.2 字体跑马灯的效果

【注意】只是设置的下面的属性,仍然不会自然的滚动;

【原因】因为焦点不在文字上,因为不会进行自动滚动;

【改进】默认的是滚动三次之后就不滚动了;

【效果】字幕进行了滚动

【一直不停滚动属性的设置】

2.5  自定义获取焦点的TextView

【使用测试】

 

【效果】

2.6 自定义控件的总结

3.九宫格使用

3.1 九宫格的效果

3.2 九宫格的书写

【默认值】默认是一列

【指定列数】3列

3.3 初始化

3.4 数据的准备 

【数据】包括文字和图片,需要准备两组数组,一个放置文字,一个放置图片;

3.5 单个条目的布局

3.6 适配器数据的填充

 

3.7 间距的调整

【说明】水平方向间距大于竖直方向的间距

【效果】

4【设置中心】设置界面一个条目布局结构 

 【说明】设置中心包含一个自动更新的设置,只有此选项勾选上才可以进行自动更新;

4.1 效果

4.2 设置点击监听

【新建类】

【在清单中配置】

【新建布局文件】

【使用线性布局进行拼接】每个条目的样式不一致,使用线性布局;当然也可以使用listView;

4.3 黑线的添加

【1】View的继承关系

4.4 黑线的效果

 

5.自定义组合控件构件布局结构

5.1【自定义的原因】

因为在同一个界面中使用到了多个相同的布局;
可以抽取出来,对代码进行优化;

5.2自定义控件的布局

 

 

 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     <RelativeLayout 
 6         android:padding="5dp"
 7         android:layout_width="match_parent"
 8         android:layout_height="wrap_content">
 9         <TextView 
10             android:id="@+id/tv_title"
11             android:textColor="#000"
12             android:textSize="18sp"
13             android:layout_width="wrap_content"
14             android:layout_height="wrap_content"/>
15         <TextView 
16             android:id="@+id/tv_des"
17             android:layout_below="@id/tv_title"
18             android:textColor="#000"
19             android:textSize="18sp"
20             android:layout_width="wrap_content"
21             android:layout_height="wrap_content"/>
22         <!-- android:clickable="false"
23             android:focusable="false"
24             android:focusableInTouchMode="false"
25                               让当前的 CheckBox不能被点击,即不能响应事件-->
26         <CheckBox 
27             android:id="@+id/cb_box"
28             android:clickable="false"
29             android:focusable="false"
30             android:focusableInTouchMode="false"
31             android:layout_alignParentRight="true"
32             android:layout_centerVertical="true"
33             android:layout_width="wrap_content"
34             android:layout_height="wrap_content"/>
35         <View
36             android:background="#000"
37             android:layout_below="@id/tv_des"
38             android:layout_width="match_parent"
39             android:layout_height="1dp"/>
40     </RelativeLayout>
41 </RelativeLayout>

5.3 通过类加载布局文件

5.3.1【问题】怎样使得三个构造方法调用同一个构造方法?

【解决办法】

5.3.2 xml文件转换为class类

【代码执行的过程】

5.3.3【自定义布局的使用】全路径的包名

【生成的效果】

5.3.5【多个条目的创建】

【可能出现的问题】

【程序运行之后的效果】

【问题的查找】

 

【正确的代码】

【最终的效果】

【注意】如果是线性布局,可能被挤到了右边;

 

6.自定义组合控件中相关方法

6.1 效果演示

6.2【源码】根据是否选中绑定文字的改变                                   

7.选中SettingItemView条目状态切换

【说明】SettingItemView条目也是View,因此可以增加监听方法

7.1 增加id;

7.2 监听事件的的添加

7.3 现在的效果

【说明】点击条目的部分时候状态会发生改变;

7.4 BUG

 【说明】点击CheckBox的选中与未选中没有反应;文字不会发生改变;

7.4.2 出现问题的原因

【说明】点击事件被拦截了,点击checkBox的事件被拦截了;

 【拦截的过程】

【事件回传的过程】

==================================

【事件回传的再讲解】

 

7.4.5 解决方法

【思路1】

【说明】实际的点击效果是点击在了SettingItemView上了;

【效果】

 【思路2】在智慧北京中进行讲解

8. sp工具类编写

8.1 选中的状态没有记录

【效果】本来选中的状态,在返回之后再点击进入之后,状态没有记录;

8.2 编写工具类进行记录设置值

【解决的办法】编写工具类进行记录

【工具类实现的功能】读写功能

【源码】

 1 package com.itheima.mobilesafe74.utils;
 2 
 3 import android.content.Context;
 4 import android.content.SharedPreferences;
 5 
 6 public class SpUtil {
 7     private static SharedPreferences sp;
 8     /**
 9      * 写入boolean变量至sp中
10      * @param ctx    上下文环境
11      * @param key    存储节点名称
12      * @param value    存储节点的值 boolean
13      */
14     public static void putBoolean(Context ctx,String key,boolean value){
15         //(存储节点文件名称,读写方式)
16         if(sp == null){
17             sp = ctx.getSharedPreferences("config", Context.MODE_PRIVATE);
18         }
19         sp.edit().putBoolean(key, value).commit();
20     }
21     /**
22      * 读取boolean标示从sp中
23      * @param ctx    上下文环境
24      * @param key    存储节点名称
25      * @param defValue    没有此节点默认值
26      * @return        默认值或者此节点读取到的结果
27      */
28     public static boolean getBoolean(Context ctx,String key,boolean defValue){
29         //(存储节点文件名称,读写方式)
30         if(sp == null){
31             sp = ctx.getSharedPreferences("config", Context.MODE_PRIVATE);
32         }
33         return sp.getBoolean(key, defValue);
34     }

8.3 sp类的使用-sp存储更新状态 

【新建类】

【效果】在返回之后的设置值仍然存在;再次打开程序的设置值仍然存在;

9.在加载时的根据设置值判断功能添加

9.1 判断功能的添加

9.2 进入主界面的延时

【到目前为止的效果】

10.自定义属性

10.1 自定义属性的意义

10.2 参照别人的源码

 10.3 模仿源码进行书写

10.4 自定义属性的使用:构造方法中获取自定义属性值

【说明】在xml中可以使用属性的前提是:

【1】具有命名空间的指定;

【2】在属性文件中进行了配置;

11 给自定义组合控件内部控件赋值

11.1 属性赋值的位置

11.2 打印属性的个数

11.3 查看自定义属性的名称和值

11.3.1 id值的打印

【注意】

11.3.2 宽度和高度的属性值

【源码的修改】

 

 

 11.4 自定义组合控件属性回顾

12 是否有密码区分对话框类型

【手机防盗模块】

12.1【功能分析】

【1】点击手机防盗会弹出密码框,在第一次回输入密码之后进入到第二个界面;

【2】在第二个界面点击返回按钮之后返回到第一个功能列表界面;

 

12.2  手机防盗功能模块的代码逻辑

【弹出对话框的框架】

【密码数据的存储和读取】

【密码数据的读取和框架的完善】

13.密码对话框的设置

13.1 效果

【说明】使我们自己设置的对话框,不是调用系统原有的,因此需要自己定义布局;

13.2 逻辑框架的搭建

13.3  布局的设置

【说明】使用线性布局,按钮需要使用权重;

【布局源码】

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical" >
 6     <TextView 
 7         style="@style/TitleStyle"  //使用原来定义的样式
 8         android:text="设置密码"
 9         android:background="#f30"/>  //原来自定义的样式的颜色是绿色的,现在将其覆盖掉为红色;
10     <!-- android:hint=""提示用户输入内容 -->
11     <EditText 
12         android:id="@+id/et_set_psd"
13         android:hint="设置密码"
14         android:inputType="textPassword"
15         android:layout_width="match_parent"
16         android:layout_height="wrap_content"/>
17     <EditText 
18         android:id="@+id/et_confirm_psd"
19         android:hint="确认密码"
20         android:inputType="textPassword"
21         android:layout_width="match_parent"
22         android:layout_height="wrap_content"/>
23     <LinearLayout 
24         android:layout_width="match_parent"
25         android:layout_height="wrap_content">
26         <Button 
27             android:id="@+id/bt_submit"
28             android:text="确认"
29             android:layout_width="0dp"
30             android:layout_weight="1"  //权重为1
31             android:layout_height="wrap_content"/>
32         <Button 
33             android:text="取消"
34             android:id="@+id/bt_cancel"
35             android:layout_width="0dp"
36             android:layout_weight="1" //权重为1
37             android:layout_height="wrap_content"/>
38     </LinearLayout>
39 </LinearLayout>

【效果】

13.4 对话初次设置密码验证过程

【取消事件的逻辑】

【源码】如果密码确认一致,此处跳转的是测试界面

 1     /**
 2      * 设置密码对话框
 3      */
 4     private void showSetPsdDialog() {
 5         //因为需要去自己定义对话框的展示样式,所以需要调用dialog.setView(view);
 6         //view是由自己编写的xml转换成的view对象xml----->view
 7         Builder builder = new AlertDialog.Builder(this);
 8         final AlertDialog dialog = builder.create();
 9         
10         final View view = View.inflate(this, R.layout.dialog_set_psd, null);
11         //让对话框显示一个自己定义的对话框界面效果
12         dialog.setView(view);
13         dialog.show();
14         
15         Button bt_submit = (Button) view.findViewById(R.id.bt_submit);
16         Button bt_cancel = (Button) view.findViewById(R.id.bt_cancel);
17         
18         bt_submit.setOnClickListener(new OnClickListener() {
19             @Override
20             public void onClick(View v) {
21                 EditText et_set_psd = (EditText) view.findViewById(R.id.et_set_psd);
22                 EditText et_confirm_psd = (EditText)view.findViewById(R.id.et_confirm_psd);
23                 
24                 String psd = et_set_psd.getText().toString();
25                 String confirmPsd = et_confirm_psd.getText().toString();
26                 
27                 if(!TextUtils.isEmpty(psd) && !TextUtils.isEmpty(confirmPsd)){ //如果密码和确实密码不为空
28                     if(psd.equals(confirmPsd)){  //如果测试密码等于确认密码
29                         //进入应用手机防盗模块,开启一个新的activity
30                         Intent intent = new Intent(getApplicationContext(), TestActivity.class);
31                         startActivity(intent);
32                         //跳转到新的界面以后需要去隐藏对话框
33                         dialog.dismiss();
34                         
35                         SpUtil.putString(getApplicationContext(), ConstantValue.MOBILE_SAFE_PSD, psd);
36                     }else{
37                         ToastUtil.show(getApplicationContext(),"确认密码错误");
38                     }
39                 }else{
40                     //提示用户密码输入有为空的情况
41                     ToastUtil.show(getApplicationContext(), "请输入密码");
42                 }
43             }
44         });
45         
46         bt_cancel.setOnClickListener(new OnClickListener() {
47             @Override
48             public void onClick(View v) {
49                 dialog.dismiss();
50             }
51         });
52     }

 13.5 测试Activity的书写

13.6 注意的问题

13.6.1 BUG1

【出现的问题1】空指针异常;

【问题的原因】

【修改】

13.6.2 BUG2

【出现的问题】空确认密码会出现空指针异常

【解决方法】

【输入密码的正常的效果】

【取消的代码逻辑的效果】

13.7 在测试页面点击返回按钮的逻辑

【问题】应该返回之后不要再弹出密码对话框

【修改源码】

【效果】

 13.8 密码的存储功能增加

【源码的增加】

13.9 确认密码对话框的添加

【布局源码】直接复制填写密码框的布局,然后修改即可;

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical" >
 6     <TextView 
 7         style="@style/TitleStyle"
 8         android:text="确认密码"  //修改此处
 9         android:background="#f30"/>
10     <!-- android:hint=""提示用户输入内容 -->
11     <EditText                                        //删除原来的填写密码框
12         android:id="@+id/et_confirm_psd"
13         android:hint="确认密码"
14         android:inputType="textPassword"
15         android:layout_width="match_parent"
16         android:layout_height="wrap_content"/>
17     <LinearLayout 
18         android:layout_width="match_parent"
19         android:layout_height="wrap_content">
20         <Button 
21             android:id="@+id/bt_submit"
22             android:text="确认"
23             android:layout_width="0dp"
24             android:layout_weight="1"
25             android:layout_height="wrap_content"/>
26         <Button 
27             android:text="取消"
28             android:id="@+id/bt_cancel"
29             android:layout_width="0dp"
30             android:layout_weight="1"
31             android:layout_height="wrap_content"/>
32     </LinearLayout>
33 </LinearLayout>

【逻辑代码】直接复制原来的填写密码框,然后直接修改即可

【运行的效果】

14. 对密码的md5的加密过程

 14.1 密码保存存在的问题

【说明】密码是明文,非常容易被破解;需要加密;

14.2 加密解决

【Java程序的运行】

【补0】因为在转化出来的字符中存在一位的数字,需要在前面补0;

【最后生辰的结果】

【md5解密收费】

【md5密码加盐】防止被破译,可以在本身的密码之后再添加自己定义的字符串;

【md5源码】

 1 import java.beans.Encoder;
 2 import java.security.MessageDigest;
 3 import java.security.NoSuchAlgorithmException;
 4 
 5 
 6 public class Md5Util {
 7 
 8     /**
 9      * @param args
10      */
11     public static void main(String[] args) {
12         //加盐
13         String psd = "123"+"abc";
14         encoder(psd);
15     }
16 
17     /**给指定字符串按照md5算法去加密
18      * @param psd    需要加密的密码
19      */
20     private static void encoder(String psd) {
21         try {
22             //1,指定加密算法类型
23             MessageDigest digest = MessageDigest.getInstance("MD5");
24             //2,将需要加密的字符串中转换成byte类型的数组,然后进行随机哈希过程
25             byte[] bs = digest.digest(psd.getBytes());
26 //            System.out.println(bs.length);
27             //3,循环遍历bs,然后让其生成32位字符串,固定写法
28             //4,拼接字符串过程
29             StringBuffer stringBuffer = new StringBuffer();
30             for (byte b : bs) {
31                 int i = b & 0xff;
32                 //int类型的i需要转换成16机制字符
33                 String hexString = Integer.toHexString(i);
34 //                System.out.println(hexString);
35                 if(hexString.length()<2){
36                     hexString = "0"+hexString;
37                 }
38                 stringBuffer.append(hexString);
39             }
40             //5,打印测试
41             System.out.println(stringBuffer.toString());
42         } catch (NoSuchAlgorithmException e) {
43             e.printStackTrace();
44         }
45     }
46 }

 

posted @ 2018-01-15 15:03  OzTaking  阅读(403)  评论(0)    收藏  举报