进入公司后开始写程序,做了一个笑话软件,嵌套在浏览器中作为一个插件使用。这个应用做了不少时间,其实应用不是太难,但是自己的基础太不好,什么东西都不会写,都要查资料,耽误了大量时间,这也给了我一个教训,工作中复制代码后患无穷啊。
该应用主要包括向服务器请求数据,解析xml,后台更新ui,处理一些屏幕响应事件等操作,都是一些很基础。代码实现过程中遇到了很多问题,有的到现在还没解决,还得急需考虑研究。
问题1: 时间的格式化问题
从服务器获取的数据是“2010-03-05 14:12:36”格式的,要将其转换为比较直观的“今天 14:12” 格式,遇到问题的原因主要是对java或者android的事件转换类不熟,此问题目前已经解决
// 取出年月日来,比较字符串即可
String str_curTime = DateFormat.format("yyyy-MM-dd",new Date()).toString();
int result = str_curTime.compareTo(time.substring(0,time.indexOf(" ")));
if(result>0){
return context.getString(R.string.haha_yesterday)+time.substring(time.indexOf(" "), time.lastIndexOf(":"));
}else if(result==0){
return context.getString(R.string.haha_today)+time.substring(time.indexOf(" "), time.lastIndexOf(":"));
}else{
return time;
}
}
这个方法写的不够专业,但是满足了需要,网友们如果有更好的办法可以贴出来,另外一点就是推荐使用Android的DateFormat类,而不是使用java的SimpleDateFormat或是其他,Android的DateFormat类的转换效率要比java中的高很多。
问题2:怎么减少ListView中的ItemView的布局层数
这个已经写过,见以前的博客, 注明:使用merge标签做为顶层标签,虽然可以减少view的层级数,但是在merge标签里设置的各种属性都不会起作用,需要在代码中设置。
问题3:中文字符设置bold格式
/**
* 设置中文汉字的字体为bold,在xml文件中设置TextView的textstyle=bold 仅对英文字符有效,必须使用
* 下述方法设置中文的字体为bold
* */
TextPaint tp = mPublisher.getPaint();
tp.setFakeBoldText(true);
问题4 : 一个小技巧
view的setTag方法的使用,在Adapter中,如和将数据和view绑定到一起,例如处理onClick,onItemClick事件时,有时会需要获取该itemView的各种数据,例如positon,id,text啊等等,在getView方法中setTag后,在其他地方我们就可以通过使用getTag方法将这个信息描述对象取出来,直接使用里面的数据,能够使代码变的更整洁。
问题5:异步加载图片 这个实验了好几种方式,都一起说说。
第一种:
在Adapter的getView方法中,判断该view是否有drawabel,如果没有,就发送一个消息,开启一个异步任务就下载图片。
总结:这样做不好,因为ListView除了绘制当前显示界面的view之外,在上下滑动时,也会不断的调用getView方法,不断的去判断是否存在这个drawable,造成资源的浪费。此外这样可能会开启很多的异步任务,即使采用队列,也会增加不断判断这个图片是否已经下载过的成本。
第二种:
给ListView绑定scroll事件,这样做的好处是每次值加载当前界面上的几个view,而不会去下载所有的item的图片,这样的好处是节省流量,坏处是第一次加载完页面时不会去触发滚动事件,也就不会去下载第一页的图片,我更倾向于这样做,这样在加上队列,应该就很好了。
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if(scrollState==OnScrollListener.SCROLL_STATE_IDLE){
int count = view.getChildCount();
if(count>0){
ArrayList<Integer> list = new ArrayList<Integer>();
for(int index=0;index<count;index++){
View vi = view.getChildAt(index);
if(vi instanceof HahaItem){
HahaItem item = (HahaItem) vi;
HahaItemInfo info = (HahaItemInfo) item.getTag();
if(mAdapter.containsKey(info.userIconUrl)) continue;
list.add(item.id);
}
}
ImageLoader loader = new ImageLoader(mHandler, list);
MxTaskManager.getInstance().excuteTask(loader);
}
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
}
});
第三种:当加载玩页面的时候,开启一个线程去下载所有的图片。
在请求数据的异步任务中,解析xml文件,完成数据的封装,存储到Adapter中的集合中,并且同时存储到一个队列中,这个队列还不能是阻塞的,因为如果是阻塞的,有可能会阻塞请求数据的异步任务。同时这个队列还必须是线程安全的,否则我们自己还得自己手动的去实现同步。
使用ConcurrentLinkedQueue这个类,他自己已经实现了同步。
当将所有的数据都添加到队列后,就要去检测下载图片的异步是否已经完成,如果完成了,就开启一个新的图片下载任务,如果没有完成,他会自动的去取队列中的数据,我们不同处理,这样能够减少频繁的开启关闭线程,提高效率。
private ConcurrentLinkedQueue<String> queue;
public ImageLoader(Handler handler, int position) {
super(handler, GETPIC_TASKID);
}
public ImageLoader(Handler handler, ConcurrentLinkedQueue<String> queue) {
super(handler, GETPIC_TASKID);
this.queue = queue;
}
@Override
protected void doTaskInBackground() {
while(true){
if(queue.isEmpty()){
break;
}
Log.i(tag, "doTaskInBackground is working: size "+queue.size());
String url = queue.poll();
Log.i(tag, "doTaskInBackground is working: url "+url);
try {
Drawable dw = AppUtils.loadDrawable(url);
mAdapter.mDrawableMap.put(url, dw);
} catch (IOException e) {
e.printStackTrace();
}
}
sendMessage(MSGID);
}
}
问题6:dip和px的设置 ?
在xml布局文件中我们既可以设置px,也可以设置dip,系统都为我们做了转换,但是在代码中怎么处理呢,很多方法都只提供了设置px的方法,例如setPadding,并没有提供设置dip的方法,按理说,应该将dip转换成px,但是转换之后,在高屏幕手机上反而出现了问题,视图变大,直接取得dimen中的数据后使用,反而不会出现任何问题,这让我很纠葛,难道方法中提供了自动转换,这个还得研究。
问题7:TextView的布局 ?
如果在TextView中显示多行文本的话,并且文本中包含数字,英文字母,就会出现排版问题,怎么解决?
这里主要涉及到的类包括Paint,
breakText方法,该方法能够检测一行显示多少文字。