这几天学习了第二天的内容,
项目源代码:http://download.csdn.net/detail/itjavawfc/8241695
主要收获了:
1)自定义属性:一般用在组合控件中
2)自定义对话框:弹出的对话框中实现输入框和按钮或其它任何你想放入的组件
3)MD5加密
4)自定义按钮背景、按钮形状、自定义动画
5)实现屏幕左右滑动效果:运用传感器
部分效果视图UI如下
要点如下:
1、演示当前扩展的麻烦性,再增加自定义组合控件的使用情境;
2、去掉setting_item_view.xml的文字,运行演示;
3、在SettingItemView里加自定义组合控件的标题方法setTitle();
4、在SettingActivity代码里写另外一个设置条的标题和描述信息赋值;
5、参照系统控件TextView讲解系控件的属性特点;
6、自定义标题属性title、描述打开属性descon、描述关闭属性descoff;
7、参照系统的命名空间写自定义的命名空间,并演示删除系统命名空间报错;
8、讲解自定命名空间;
9、演示运行时报错;
10、找到目录platforms\android-16\data\res\values\attrs.xml,参照TextView讲解;
11、在工程里res/values目录下创建attrs.xm文件内容如下:
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="SettingItemView"> <attr name="title" format="string" /> <attr name="desc_on" format="string" /> <attr name="desc_off" format="string" /> </declare-styleable> </resources>
12、属性使用,讲解两个参数的构造方法:
在布局文件里面所定义的所有属性,都会被封装到AttributeSet 的属性集合里面;
13、得到属性值(attrs.getAttributeValue(0))并打印出来;
14、使用更方便的方法:
attrs.getAttributeValue("http://schemas.android.com/apk/res/com.itheima.mobilesafe", "title");
13、把得到的值关联到各个控件里去;
14、删除SettingActivity用代码设置的描述信息和标题信息;
15、在布局文件里多次使用自定义控件,并演示;
1、声明一个View对象 继承相对布局,或者线性布局 或者其他的ViewGroup。
2、在自定义的View对象里面重写它的构造方法。在构造方法里面就把布局都初始化完毕。
3、根据业务需求 添加一些api方法,扩展自定义的组合控件;
4、希望在布局文件里面 可以自定义一些属性。
5、声明自定义属性的命名空间。
xmlns:itheima="http://schemas.android.com/apk/res/com.itheima.mobilesafe" 6、在res目录下的values目录下创建attrs.xml的文件 声明你写的属性。 <declare-styleable name="SettingItemView"> <attr name="title" format="string" /> <attr name="desc_on" format="string" /> <attr name="desc_off" format="string" /> </declare-styleable>
7、在布局文件中写哪些你自定义的属性。
8、使用这些定义的属性。自定义View对象的构造方法里面 有一个带两个参数的构造方法
布局文件里面定义的属性都放在 AttributeSet attrs
获取那些定义的属性。
1、画图两个对话框的样子;
2、写大体逻辑代码;
showLostFindDialog();//进入手机防盗的对话框;
isSetupPwd();//判断是否设置过密码,用到共享偏好。 private boolean isSetupPW(){ String password = sp.getString("password", null); return !TextUtils.isEmpty(password); } showSetupPwdDialog(); showEnterDialog(); 布局文件(dialog_setup.password.xml): <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="300dip" android:layout_height="wrap_content" android:orientation="vertical" > <TextView android:layout_width="300dip" android:layout_height="40dip" android:background="#66ff6600" android:gravity="center" android:text="设置密码" android:textColor="#000000" android:textSize="20sp" /> <EditText android:id="@+id/et_setup_pwd" android:layout_width="280dip" android:layout_height="wrap_content" android:hint="请输入密码" /> <EditText android:id="@+id/et_setup_pwd_confirm" android:layout_width="280dip" android:layout_height="wrap_content" android:hint="请再输入密码" /> <LinearLayout android:layout_width="280dip" android:layout_height="wrap_content" android:gravity="center" android:orientation="horizontal" > <Button android:id="@+id/ok" android:layout_width="140dip" android:layout_height="wrap_content" android:text="确定" > </Button> <Button android:id="@+id/cancel" android:layout_width="140dip" android:layout_height="wrap_content" android:text="取消" > </Button> </LinearLayout> </LinearLayout>
showSetupPwdDialog();对话框的代码:
确定按钮:
String password= et_setup_pwd.getText().toString().trim(); String password_confirm = et_setup_pwd_confirm.getText().toString().trim(); if(TextUtils.isEmpty(password)||TextUtils.isEmpty(password_confirm)){ Toast.makeText(getApplicationContext(), "密码为空", 0).show(); return ; } if(password.equals(password_confirm)){ //密码相同-保存并且进入手机防盗页面 Editor editor = sp.edit(); editor.putString("password", password); editor.commit(); dialog.dismiss(); //进入手机防盗页面 Log.i(TAG, "密码已经保存,进入手机防盗页面"); }else{ Toast.makeText(getApplicationContext(), "密码不一致", 0).show(); return ; }
取消按钮
前提
dialog = builder.show(); dialog.dismiss();
3、设置密码对话框部署并找出不好看的原因,并且修改;
修改大小小于父控件;
4、设置密码对话框变得好看。加ID,并实现点击代码逻辑;
初始化ID、
取消事件--dialog抽取出去:
确定事件:
5、拷贝进入密码对话框布局文件,并命名为:dialog_enter_password.xml
6、拷贝进入密码对话框的代码并修改
7、总结:不同的布局文件里面各自的ID是可以重名的
但是同一个布局文件里,相同的ID不允许重名的;
本知识点需要:手机能共享网络
1、创建2.3模拟器展示对话框(有黑背景),4.12和2.3的区别,并说明原因
2、解决在2.3对话框有黑背景的问题
设置背景为白:android:background="#ffffff" alertDialog = builder.create(); alertDialog.setView(view, 0, 0, 0, 0); alertDialog.show();
1、为什么要加密--不加密的不安全
知识拓展:
root权限
买过来的手机是没有root权限的;
Root权限是linux系统的超级管理员权限;
如果你的手机刷机了,那就有root权限
模拟器能看到data/data里的数据,是为了方便开发者
没有root权限的手机是看不到data/data
有root权限的符号:#
没有root权限的符号:$
查看config.xml命令
cat config.xml
2、md5算法
不可逆的:原文--》密文、用系统的API可以实现;
123456 ---密文
1987 ----密文;
算法步骤:
1、用每个byte去和11111111做与运算并且得到的是int类型的值:
byte & 11111111;
2、把int 类型转成 16进制并返回String类型;
3、不满八个二进制位就补全;
public static void main(String[] args) throws NoSuchAlgorithmException { MessageDigest digest = MessageDigest.getInstance("md5"); String password = "123456"; byte [] result = digest.digest(password.getBytes()); StringBuffer buffer = new StringBuffer(); for(byte b : result){ //0xff是十六进制,十进制为255 int nuber = b & 0xff; String str = Integer.toHexString(nuber); if(str.length()==1){ buffer.append("0"); } buffer.append(str); } //这就是MD5加密得到的值 System.out.println(buffer); }
没有事先准备的算法异常;
4、网站验证算法是否正确(www.cmd5.com)、加密再加密再演示
5、密码加盐
6、合并代码进入工程(MD5Utils)
7、删除config.xml (rm *),并演示;
准备:需要谷歌文档
1、演示百度输入法设置向导
2、创建LostFindActivity,在HomeActivity激活并可以进入;
判断是否用户设置向导,如果没有就进入设置向导;
3、创建Setup1Activity
4、自定义标题样式命名:text_title_style
5、自定义文本样式text_content_style(图片名star_big_on)。
6、小点图片(presence_online、presence_invisible)
1、在android-16\data\res\values\styles.xml看一下系统定义的Button样式,看一下低版本和版本的区别
2、看一下帮助文档(Develog/App Resources/Resource Types)Button如何自定义;
创建drawble目录 ,拷贝文档中定义的案例;
3、用美图秀秀自定义按钮背景(50*50),命名:button.xml
4、用别人的图片:button_bg.xml,用自己准备好的图片;
5、把做好的背景设置到设置密码对话框和输入密码对话框;
6、进模拟器设置里设置显示边框。
1、讲出几个布局文件的共性;
2、拷贝老版本布局文件的代码或者敲一遍布局文件代码;
3、自定义下一个、上一个按钮样式;
4、如果是拷贝的话把布局文件报错的地方解决完成;
5、创建多个Setup2Acitvity、Setup3Acitvity、Setup4Acitvity;并在功能清单注册;
6、定义点击事件在样式里:
7、代码里实现;
8、从手机防盗页面到第一个设置页面Intent;
9、拷贝手机防盗页面,并完成跳转;
1、前提:重新进入设置向导控件没点击效果
2、看文档Develop/API Guides/App Resources/Drawable/Shape Drawable
单词:corners : 角 ; gradient :梯度; solid:固定的; stroke: 边框--可以做下划线
Rectangle : 矩形;dash :破折号 gap:间隙;
3、拷贝实例代码,文件命名(gradient_box.xml)
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <corners android:radius="5dip"/> <gradient android:startColor="#ff0000" android:endColor="#00ff0000"/> <solid android:color="#ffffff" /> <stroke android:width="3dip" android:color="#000000" android:dashGap="5dip" android:dashWidth="5dip"/> </shape>
4、默认状态gradient_box.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <corners android:radius="5dip"/> <solid android:color="#ffffff" /> </shape>
5、按下去状态状态gradient_box_press.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <corners android:radius="5dip"/> <solid android:color="#22000000" /> </shape>
6、把两个状态整合在shape_bg.xml
7、并使用
1、anim
2、下一步动画 位移动画
解释-100%p p:代表父窗体,100%:代表整个窗体,-:代码向左移动;
tran_out.xml
<?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> Tran_in.xml <?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>
3、使用动画:
overridePendingTransition(R.anim.tran_in, R.anim.tran_out); 上一步动画 Tran_pre_out.xm; <?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> Tran_pre_in.xm <?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> 4、使用动画: overridePendingTransition(R.anim.tran_pre_in, R.anim.tran_pre_out);
知识拓展:
有些手机上无法出现动画:是因为把播放动画的功能关闭了,为什么关闭呢,是为什么省点;
Android手机省电的几个技巧:
1.不要用动态的壁纸;
2.屏幕亮度调低一些;
3.3G网络关闭使用,2G网络,当然是不需要上网的情况下;
4.关闭手机执行动画;
5.经常杀一下后台的应用;
1、在Setup1Activity定义一个手势识别器;GestureDetector
3、抽取next()--->shownext();代码 public class Setup1Activity extends Activity { //1、声明一个手势识别器 private GestureDetector gestureDetector; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_setup1); //2、初始化一个手势识别器 gestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener(){ //当时手指在屏幕上滑动时调用的方法 @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if((e2.getRawX() - e1.getRawX()) > 200){ //显示上一个页面:从左向右滑动 System.out.println("显示上一个页面"); return true; } if((e1.getRawX() - e2.getRawX()) > 200){ //显示下一个页面:从右向左滑动 shownext(); System.out.println("显示下一个页面"); return true; } return super.onFling(e1, e2, velocityX, velocityY); } }); } //3、用手势识别器,检查屏幕上的手势识别器 @Override public boolean onTouchEvent(MotionEvent event) { gestureDetector.onTouchEvent(event); return super.onTouchEvent(event); } public void next(View view){ shownext(); } private void shownext() { Intent intent = new Intent(this,Setup2Activity.class); startActivity(intent); finish();//关闭当前的页面 overridePendingTransition(R.anim.tran_in, R.anim.tran_out); } }
1、使用注册
2、抽取到基类BaseSetupActivity
3、屏幕竖值方向的滑动;
if(Math.abs((e2.getRawY() - e1.getRawY())) >100){ Toast.makeText(getBaseContext(), "不能这样滑动", 0).show(); return true; } 7、屏蔽滑动慢 if(Math.abs(velocityX)< 200){ Toast.makeText(getBaseContext(), "滑动有些慢哥们", 0).show(); return true; }