Android:ListView 适配器中的 OnClickListener 有时无法正常工作
Android: OnClickListener in ListView Adapter not Working sometimes
我有一个包含多个项目的 ListView,其中包含进度条。我目前有一个线程设置来更新每个条形图的进度,如下所示:
h = new Handler();
h.postDelayed(new Runnable() {
public void run() {
game.update();
h.postDelayed(this, 20);
}
}, 20);
然后我像这样更新每个列表项的进度:
progress += timeInc;
if (progress >= progressMax)
completeWork();
updateView();
updateView 方法执行以下操作:
public void updateView() {
try {
activity.runOnUiThread(updateView);
} catch (Exception e) {
e.printStackTrace();
if (listView != null)
listView.post(updateView);
}
}
所以基本上,我每秒调用几次 notifyDataSetChanged。当我不这样做时,ProgressBar 的进度不会移动,但是我可以正常单击 Items。但是多次调用它时,有时不会触发列表中项目的 OnCLickListener。我认为它可能会被 notifyDataSetChanged 的调用以某种方式打断。
这是我在适配器中应用我的 OnClickListener 的地方:
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
if (files != null) {
if (!files.get(position).isClicked()) {
// FAILED TO INTERACT:
}
}
}
});
listView.setAdapter(fileAdapter);
updateView = new Runnable() {
@Override
public void run() {
fileAdapter.notifyDataSetChanged();
listView.invalidate();
}
};
这里的问题是什么?还有什么其他方法可以更新进度条而不必多次调用此方法?
更新:我减少了该方法的调用次数,现在点击响应更快。但它有时仍然会发生。
谢谢。
我认为导致 onClickListener
有时不工作的主要原因是您的 Main Thread
(UI Thread
) 很忙。因为你每秒更新UI,而且你的项目比较多,所以工作量很大 --> 有一段时间你click on Item
,Main Thread
很忙,没法回复。
想出了解决办法。我没有更新整个列表,而是按如下方式更新了单个项目:
public boolean updateProgress(File file) {
if (listView == null)
return false;
int position = files.indexOf(file);
int first = listView.getFirstVisiblePosition();
int last = listView.getLastVisiblePosition();
if (position < first || position > last) {
return false;
} else {
View convertView = listView.getChildAt(position - first);
ProgressBar bar = (ProgressBar) convertView.findViewById(R.id.progress_bar);
if (file.isWorking()) {
bar.setVisibility(View.VISIBLE);
bar.setMax(file.progressMax);
bar.setProgress(file.progress);
bar.invalidate();
} else {
bar.setVisibility(View.GONE);
}
return true;
}
}
我有一个包含多个项目的 ListView,其中包含进度条。我目前有一个线程设置来更新每个条形图的进度,如下所示:
h = new Handler();
h.postDelayed(new Runnable() {
public void run() {
game.update();
h.postDelayed(this, 20);
}
}, 20);
然后我像这样更新每个列表项的进度:
progress += timeInc;
if (progress >= progressMax)
completeWork();
updateView();
updateView 方法执行以下操作:
public void updateView() {
try {
activity.runOnUiThread(updateView);
} catch (Exception e) {
e.printStackTrace();
if (listView != null)
listView.post(updateView);
}
}
所以基本上,我每秒调用几次 notifyDataSetChanged。当我不这样做时,ProgressBar 的进度不会移动,但是我可以正常单击 Items。但是多次调用它时,有时不会触发列表中项目的 OnCLickListener。我认为它可能会被 notifyDataSetChanged 的调用以某种方式打断。
这是我在适配器中应用我的 OnClickListener 的地方:
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
if (files != null) {
if (!files.get(position).isClicked()) {
// FAILED TO INTERACT:
}
}
}
});
listView.setAdapter(fileAdapter);
updateView = new Runnable() {
@Override
public void run() {
fileAdapter.notifyDataSetChanged();
listView.invalidate();
}
};
这里的问题是什么?还有什么其他方法可以更新进度条而不必多次调用此方法?
更新:我减少了该方法的调用次数,现在点击响应更快。但它有时仍然会发生。
谢谢。
我认为导致 onClickListener
有时不工作的主要原因是您的 Main Thread
(UI Thread
) 很忙。因为你每秒更新UI,而且你的项目比较多,所以工作量很大 --> 有一段时间你click on Item
,Main Thread
很忙,没法回复。
想出了解决办法。我没有更新整个列表,而是按如下方式更新了单个项目:
public boolean updateProgress(File file) {
if (listView == null)
return false;
int position = files.indexOf(file);
int first = listView.getFirstVisiblePosition();
int last = listView.getLastVisiblePosition();
if (position < first || position > last) {
return false;
} else {
View convertView = listView.getChildAt(position - first);
ProgressBar bar = (ProgressBar) convertView.findViewById(R.id.progress_bar);
if (file.isWorking()) {
bar.setVisibility(View.VISIBLE);
bar.setMax(file.progressMax);
bar.setProgress(file.progress);
bar.invalidate();
} else {
bar.setVisibility(View.GONE);
}
return true;
}
}