我必须用ListView
填写需要时间收集的文字信息。
我的方法是使用AsyncTask来执行后台作业,但是当结果到达时将文本设置为TextView会减慢列表:每次调用getView()
时列表都会滞后。
这是我的AsyncTask
班级
private class BreadcrumbTask extends AsyncTask<FFile, Void, String>{
private WeakReference<TextView> mTextView;
public BreadcrumbTask(TextView textView){
mTextView = new WeakReference<TextView>(textView);
}
@Override
protected String doInBackground(FFile... params) {
// text processing
}
@Override
protected void onPostExecute(String result) {
if (mTextView != null){
TextView tv = mTextView.get();
if (tv != null)
//this line blocks the UI. if I comment it the lag is gone
tv.setText(result);
}
// mTextView.setText(result); }
我在getView()中创建了一个新任务,然后执行它。
问题显然来自tv.setText(result)
中的onPostExecute()
。当我评论列表很好地流动。那么如何在不降低用户界面的情况下更新TextView
?
答案 0 :(得分:1)
使用ViewHolder模式。
http://developer.android.com/training/improving-layouts/smooth-scrolling.html
在视图持有人中保留视图对象
在滚动ListView期间,您的代码可能经常调用findViewById(),这会降低性能。即使适配器返回一个膨胀的视图以进行回收,您仍然需要查找元素并更新它们。重复使用findViewById()的方法是使用“视图持有者”设计模式。
ViewHolder对象将每个组件视图存储在标记内 布局的字段,因此您可以立即访问它们而不需要 需要反复查找它们。首先,您需要创建一个类 保持您的确切观点。例如:
static class ViewHolder {
TextView text;
TextView timestamp;
ImageView icon;
ProgressBar progress;
int position;
}
然后填充ViewHolder并将其存储在布局中。
ViewHolder holder = new ViewHolder();
holder.icon = (ImageView) convertView.findViewById(R.id.listitem_image);
holder.text = (TextView) convertView.findViewById(R.id.listitem_text);
holder.timestamp = (TextView) convertView.findViewById(R.id.listitem_timestamp);
holder.progress = (ProgressBar) convertView.findViewById(R.id.progress_spinner);
convertView.setTag(holder);
其他一些例子:
http://xjaphx.wordpress.com/2011/06/16/viewholder-pattern-caching-view-efficiently http://www.jmanzano.es/blog/?p=166
答案 1 :(得分:0)
您无法从其他线程更新UI。但您可以使用Handler动态更新UI。在类中定义一个处理程序并按如下方式使用它:
<强>声明:强>
String result = "";
Handler regularHandler = new Handler(new Handler.Callback() {
public boolean handleMessage(Message msg) {
// Update UI
if(msg.what==3){
if (mTextView != null){
TextView tv = mTextView.get();
if (tv != null){
//this line blocks the UI. if I comment it the lag is gone
tv.setText(result);
}
}
}
return true;
}
});
您在onPostExecute中的代码
@Override
protected void onPostExecute(String result) {
//store the value in class variable result
this.result = result;
handler.sendEmptyMessage(3);
}
答案 2 :(得分:0)
@Override
protected void onPostExecute(String result) {
if (mTextView != null){
TextView tv = mTextView.get();
if (tv != null)
//this line blocks the UI. if I comment it the lag is gone
tv.setText(result);
}