标签:
1.1添加黑名单的ui
拦截类型修改为一组RadioGroup,里面三个RadioButton,RadioGroup可以指定排列方式
其它的都简单,记得定义好ID,顺便抽取点样式就可以了,最后两个Button可以设置状态选择器.
如果不确定LinearLayout有多高,就设置为0dp,权重为1,这样它会自己去填充空白,而不是覆盖.
1.2 电话号码的文本输入框
1.2.1安卓下特殊的图片资源 .9.png 图片
安卓自带的工具:sdk-tools-draw0-pathch
如果是在两侧选定黑点,竖向依据黑点间像素块拉伸,上下选择黑点,水平方向就依据这两个黑点链接的像素块.
一般9-patch 就拉伸四个角落,保存就是.9.png图形.即便图片被拉伸,也不会出现很奇怪的变形.
1.2.2 ,通过XML文件定义背景资源
帮助文档>>Develop>>Resource Type>>Drawable>>Shape Drawable
实际上是一个xml文件.根节点为:shape,最常用的属性是shape=”rectangle”//矩形
查看文档可以看到shape中所有的子节点.
Corners子节点,四个角的弧度.//传说中的圆角
Graient 子节点,渐变色 属性startColor,endColor,开始,结束的颜色
Padding:内容据边框的距离
Siez:一般资源文件都可以自动拉伸,不会去配置它
Solid:固定颜色,跟Graint相互冲突.
Stork:图形的边框,可以指定Color颜色,边框宽度width,dashGap:虚线间空白的宽度,dashwidth:虚线本身的宽度.
不过一般还是要美工来做//废话.
1.2.3 文本输入框的样式修改:修改它的背景资源
点击输入内容之后,边框会变色//获取到了焦点之后,失去焦点也会变色.
参照上面的shape子节点做出来获取焦点时候的背景,失去焦点的背景两个XML文件.
//蓝配红,大傻蛋
//其实获取焦点,失去焦点,就是状态选择器,定义一个状态选择器包含这两个XML文件即可.
如果只有一个文本输入框,它默认就是一直获取焦点的状态.
1.2.4 添加界面的业务逻辑
①radiogroup.getCheckedRadioButtonId()//获取选中的单选框的id
Checkbutton 属性,默认选中.
点击保存就添加进数据库,判断是否添加成功,并把这个结果返回上级页面.
黑名单号码是不能重复的,//查询,判断返回结果即可
②在显示列表页面中,重写onAcrivityResult方法,判断返回的结果,并显示在页面上(其实这个结果显示也可以放在添加页,不过在显示列表页更加符合用户的使用习惯,也可以通过结果来获取list集合(所有黑名单用户)再次重置适配器)
1.2.5, 显示所有黑名单号码的页面业务逻辑
①在dao类中添加一个获取所有黑名单用户的功能,findAll(),同时要创建一个业务ben(方便储存)
②然后db.query,遍历cursor 结果集添加进集合中即可. 最后记得cursor.close(),db.close()
③在显示页面自定义适配器,把list集合里所有元素放到适配器里(代码略)
④创建一个item的样式文件
参考样式
1.2.4 数据ui显示细节
①centerVertical 控件竖直居中显示
②点击垃圾箱删除当前号码(获取当前的电话号码即可)
③判断删除的结果,删除完之后,移除listview绑定集合里面的数据lv.remove(list)
也可以重新获取一次所有数据,不过这样可能会比较耗时(要放到子线程之类)
同时adapter.notifyDataSetChange()//通知适配器更新数据
④当黑名单列表里一条内容都没有的时候,显示一个图片或文本信息都可以
这里不通过帧布局,而是相对布局,也有visibile的效果.
//在适配器中获取条目的数量的时候判断是否为0,来作为显示图片的依据.
1.2.5 ListView的优化(重要)
①复用convertView//判断是否为空
②ListView快速滚动,定义属性fastScrollEnabled=true即可
③findViewByID()查找View中的控件,会遍历所有的子控件的id,比较消耗时间.
定义一个类ViewHolder //用来存储子控件的容器
Class ViewHolder{
控件1的引用
控件2的引用
控件3的引用
}
用法:如果convertView为空,创建它的时候,同时也创建ViewHolder对象.
然后在把其中的成员属性赋值,找到对应的控件.
这样复用convertView的时候就不用重新寻找子孩子了.
covertView.setTag(ViewHolder)//把子控件容器保存在covertView中
④当convertView不为空的时候,可以通过getTag()获取子控件容器ViewHolder对象.
2.优化应用程序的用户体验
①当黑名单列表的用户非常多的时候(这个场景在显示所有网站用户,或者后台管理,或者日常事务之类有大量数据要显示在页面上时都可以参考)所以,需要把这个耗时操作放到子线程中,用runUiThead()去更新适配器(适配器看做更新ui的操作)
创建一个LinearLayout,放置一个图片和一个文本,获取信息的时候就设置为可见,获取完就设置可见.
②优化了之后,添加黑名单也会卡一段时间,因为从数据库中重新获取了数据
添加页面返回结果的时候intent携带一个黑名单的封装对象,然后在显示页面直接添加到集合里.
③同理,删除的时候也可以做这样的优化
3.应用程序优化的概念和原则
①本质上是拆东墙补西墙,时间,空间互换
时间换时间:例如电脑开机启动项,禁用了开机启动项虽然开机快了,但是打开程序的时候时间慢了.
空间换时间:(空间小,时间慢),例如网络歌曲,不永久保存在本地硬盘上,但是访问网络读数据需要时间.
图库:开机和sd卡装载的时候遍历sd卡,把路径保存在数据库.
空间换空间:(一块空间给另一个空间使用)参考电脑的虚拟内存,把内存中一部分暂时未使用的数据保存在硬盘上,使用的时候,或内存充足的时候提取出来.
ramdisk软件:把内存空间当做硬盘空间使用,速度要比固态硬盘还快(但是贵啊)
时间换空间:(时间快,空间大)io流中,流对接的byte数组,byte数组越大,占的空间越大,执行速度越快.
4.骚扰拦截的业务逻辑
原理:监听电话和短信,需要长期在后台运行,所以需要创建服务
①创建一个服务,并配置清单文件
②在服务创建的时候,创建一个电话监听器TelephonyManager = getSystemService(XXX);
Tm.listener(监听器,监听状态(通话数据,通话状态,手机信号等等));
监听电话:PhoneStateListener.LISTEN_CALL_STATE
自定义监听器.重写onCallStateChange(int state,String)//当呼叫状态发生改变的时候调用
判断呼叫状态tm.Call_STATE_IDIE空闲状态
tm.CALL_STATE_RINGING//响铃状态
tm.CALL_STATE_OFFHOOK://接通状态
在响铃的时候就获取电话(参数上的String),匹配数据库中的数据,查询是否为黑名单号码,符合拦截模式.
③服务注销的时候,取消注册tm.listener(listener,tm.listener_NONE);
Listener= null //把监听器快速回收
④在设置界面里要允许用户是否开启监听器.
通过自定义view的状态来判断是否开启服务
开启服务:startService(intent);
关闭服务:stopService(intent);
额外①:通过服务的状态回显开关效果(保存sp也可以,不过不严谨),获取服务的运行状态工具类创建
ServiceStateUtils 检查服务运行状态的工具类
//serviceFullName服务类的全路径
创建方法isServiceRunning(String serviceFullName,Context context){
//获取手机上的进程管理器
ActivityManager am = context.getSystemService(XXX);
//得到系统里正在运行的服务
List(RunningService) lists= am.getRunningService(获取正在运行的服务最大的数量,200以内)
遍历集合, list.service(得到正在运行服务的主键名).getClassName(得到服务的类全名称);
判断是否存在传入的serviceFullName集合,
}
标签:
原文地址:http://www.cnblogs.com/adventurer/p/5589332.html