1,自定义吐司显示风格
①创建一个布局文件(代码注册的View看不出效果,所以还是定义布局文件比较好)
这里的背景是.9图片会根据包裹内容来拉伸
②在显示自定义吐司的界面,显示的吐司通过View.inflate()创建
③在设置中心增加一条修改归属地显示风格.
{"半透明","活力橙","卫士蓝","金属灰","苹果绿"};
点击之后弹出一个单选对话框.
builder.setSingleChoiceItems(对应选择的条目,默认选中的(回显sp),监听器(){
重写的方法(){
传进来的参数就是被选中的条目
保存选中的条目到sp中
显示出来后关闭它本身.
}
});
④在服务类获取到选中的条目,并赋值给对应的View即可
2,修改归属地显示的位置
目标:用户可以拖动归属地吐司显示的位置
①param.x(参照当前窗体的位移距离)距离水平方向的距离
param.y 距离竖直方向的距离,并更新给窗体:wm.updateViewLayout(view,param)
吐司默认是以手机中央为出发点.
Param.gravity = Gravity.LEFT + Gravity.TOP//坐标系为窗体的左上角
②用户拖动,就是触摸位置的偏移量
View.onTouchListener(){
onTouch(v,event){
判断event的动作
event.Action_Down:
获取按下的坐标
event.Action_MOVE:
获取新的坐标(移动一次获取一次)然后把偏移量赋值给param.x.y
event.Action_up:
//返回为true会一直获取触摸动作
}
};
③拖动的时候没有日志打印.
因为para.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE设置不可触摸,删除.
还需要修改Type类型 Type_PRIORITY_PHONE//跟电话相同优先级的窗体类型,可以相应触摸和点击事件 代表的数字2007,Toast:2005,//其它类型用的限制大一些.
④需要权限SYSTEM_ALERT_WINDOW
额外:param 指定gravity属性,指定窗体类型,配置权限.
3.拓展:小火箭效果
①小火箭实际上是两张图片的切换,可以通过animation-list节点的xml文件定义动画
通过帮助文档>>>Develop>>>APP Resource>>Animation and Graphics>>OverView
可以看到xml文件定义的动画
两张图片每个播放200毫秒即可
②小火箭要在桌面上显示出来,所以要创建一个服务,监听桌面显示事件.
对象windowmanager,创建一个imagerView,设置动画到它的背景属性中
通过AnimationDrawable xx = iv.getBackground();//获取出来再强转
xx.Start()
param参数,拷贝吐司的就好了.
修改type和不可触摸属性.指定对其方式
wm.addView(xx,param);
③定义一个主界面去开启和停止服务
④添加权限System_ALERT_WINDOW//系统级别的窗体权限
⑤火箭要能在窗体上来回移动
注册触摸事件,获取用户手指移动的偏移量(移动距离-初始距离)赋值给param
⑥火箭发射动作,
MotionEvent.ACTION.UP //当手指松开的时候
判断if(parmas.y>300&¶ms.x>100&¶m.x<300)//用尺子去量
其实烟雾效果是一个透明的activity//因为发射的时候界面不能点击
Background 和Src的区别
src的范围比Background要小一些(参考盒子模型,内容和背景)
配置这个界面成透明风格:@android:style/theme.transLcent.noTitleBar
⑦当火箭发射的时候开启意图即可(界面开启XX秒之后finsh()掉)
startActivity()//报错,如果是从非 activity中启动activity
需要开启一个新的任务栈(FLAG_ACTIVITY_NEW_TASK)
因为服务里是没有任务栈的
intent.setFlag(Intent.FLAG_ACTIVITY_NEW_TASK)设置一个flag即可.
⑧发射火箭的时候,定义一个子线程,for循环把Y轴每隔XX秒依次减少即可(默认出发点在屏幕左上角,屏幕下方Y轴就会增加)
由于是在子线程中更新ui,通过handler.post(new Runable(){更新ui逻辑});
额外:火箭发送完毕就应该消失掉,并关闭activity
火箭发送的时候,烟雾应该延迟XX秒再出现.
希望小火箭可以移出屏幕:WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
4.短信备份的时候
常用工具里,新建一个功能,短信备份
①点击备份,通过内容提供者读取短信数据库mmssms,sms表
记得加读写短信数据库的权限,通过xml文件序列化保存信息.
每一条短信都是一个节点(info,sms名字随意啦)
然后通过添加子节点写入信息即可(信息放在标签之间的文本中serializer.text()添加即可)
文件保存在外部储存卡上,记得也要加权限读写sd卡
最后记得关闭输出流
②短信备份的细节问题:
异常不能全部捕获,要分别提示
短信数量很多的情况下,序列化保存需要花费很多时间,所以要放到子线程
放到子线程就不能直接打印吐司了,要通过handler发送消息到主线程.
handler.sendEmptyMessage(常量)//发送空信息,不用创建Message对象,简化方式.
线程开启之前,创建一个ProgressDiaLog()//进度条,设置水平显示,并show()出来
Pd.setMax(cursor.getCount())//获取返回结果集最大行数为进度条的最大值
循环之前设置为1,每备份一条进度就加1.
在finally之中关闭对话框
5,代码的分工编写
假设两个工程师 ①小A ②小B
小A对界面比较熟悉 编写ui相关逻辑,需要实现业务逻辑就调用B的工具类
小B对后台比较熟悉 编写业务实现的工具类,需要考虑实现业务逻辑的细节.
如:前面的短信,B编写了备份的工具类,还需要考虑到ProgressDiaLog的进度问题.
6_接口和回调(重要)
场景,客户改需求,不要进度条对话框,而是要界面显示进度条
小A:通过ProgressBas控件实现,让它跟界面的条目表框重叠就能暂时隐藏起来.
也可以让进度条覆盖短信备份的整个条目
小B:修改工具类,设置pb的最大进度和循环进度
然后客户又要改回来(版本控制checkOut出来即可)
其它需求:又要对话框,又要进度条
6.1 实际开发中,场景应该是这样的:
小A :你暴露一个接口给我
小B :我提供一个回调给你
目的:降低两个人业务之间的耦合性.
6.2 实现步骤
小B 在代码中另外抽取一个方法,返回最大值和进度,这样就不用关心是什么控件来使用.
在工具类中定义一个接口,是备份逻辑的回调
接口中定义两个抽象方法:一个设置最大值,一个短信备份的进度
然后在具体备份的方法中,参数不再传入控件,而是传入这个接口的实现类(或匿名对象),然后把最大值和进度设置到这个实现类的方法中.
小A,使用备份的方法,传入接口的实现类,重写这两个方法,可以获取到设置的最大值和进度.
为什么使用接口:因为调用这个备份的方法,是必须要重写获取最大值和进度的方法.
其实谷歌在设置代码的时候就是采用的这样一种模式,不关心具体实现的步骤,只负责建立链接.
7.1 短信的还原......................
按接口和回调的方式写
8,程序管理器的ui (程序图标,程序名,占用内存,卸载按钮)
8.1定义一个activity,程序管理界面,参考ui;
进行home界面的跳转设置.
8.2手机可用内存,SD可用空间的数据填充
①机身内存 ROM(呵呵) 运行内存RAM,可用内存是指的机身内存
②定义系统信息的工具类,可以获取机身内存和可用内存
getInternalStorageSize()//自定义名称,获取系统内置存储空间的总大小
File file = Environment.getDataDirectory()//返回机身内存目录
Long length = file.getTotalSpace()//获取当前分区的大小
getInternalStorageFreeSize()//自定义名称,获取系统内置存储空间可用大小
File file = Environment,getDataDirectory()//返回机身内存目录
Long length = file.getFreeSpace()//获取可用分区大小
//获取SD卡可用大小方法,略
③把数据展示在页面上.
格式化器:Formatter.formatFileSize(上下文,数据);//格式化sd卡可用空间的数据显示
装在国产手机上可能获取的内存空间和储存卡空间为0
因为有的手机是不支持外部存储卡(sd卡)的(为了把机身内存多卖点钱,很黑的),或者是直接把一块SD卡焊死在主板上,修改了系统的API导致获取的数据不正常.
④程序管理器的数据获取
android下业务方法的分包:mobliesafe.engine包,放置业务逻辑相关的代码
参考类名:AppInfoProvider.class,创建一个业务bean储存应用程序的信息.
应用程序的图标用Drawable保存,因为它的范围比BitMap更广.
应用程序的名称,包名,app大小
新的api 程序管理器 PackageManager类,有各种各样的信息关于应用的.
获取方式PackageManager pm = Context.getPackageManager();
可以获取应用程序的图标,权限,标签,等很多信息
pm.getInstalledPackagers(flag(附加的可选标记,0))//返回一个packageinfo的集合.
Packageinfo.packagename //包名
packageinfo.applicationInfo //通过安装包得到应用程序的信息
Drawable appicon = packageinfo.applicationInfo .loadicon(pm)
String appname = packageinfo.applicationInfo.loadLabel(pm).toString()
应用程序的apk文件都是在/data/app目录下,系统自带的System/app目录下
packageinfo.applicationInfo.sourceDir;//得到文件的完整路径
通过路径可以获得文件对象,再通过文件对象file.length返回文件大小.
最后给业务bena 保存信息即可