进入公司后开始写程序,做了一个笑话软件,嵌套在浏览器中作为一个插件使用。这个应用做了不少时间,其实应用不是太难,但是自己的基础太不好,什么东西都不会写,都要查资料,耽误了大量时间,这也给了我一个教训,工作中复制代码后患无穷啊。
该应用主要包括向服务器请求数据,解析xml,后台更新ui,处理一些屏幕响应事件等操作,都是一些很基础。代码实现过程中遇到了很多问题,有的到现在还没解决,还得急需考虑研究。
问题1: 时间的格式化问题
从服务器获取的数据是“2010-03-05 14:12:36”格式的,要将其转换为比较直观的“今天 14:12” 格式,遇到问题的原因主要是对java或者android的事件转换类不熟,此问题目前已经解决
public
static
String getLocalTime(Context context, String time){
//
取出年月日来,比较字符串即可
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格式
mPublisher
=
(TextView)
this
.findViewById(R.id.haha_publisher);
/**
* 设置中文汉字的字体为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的图片,这样的好处是节省流量,坏处是第一次加载完页面时不会去触发滚动事件,也就不会去下载第一页的图片,我更倾向于这样做,这样在加上队列,应该就很好了。
mListView.setOnScrollListener(
new
OnScrollListener() {
@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
class
ImageLoader
extends
MxAsyncTaskRequest {
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方法,该方法能够检测一行显示多少文字。