【发布时间】:2014-04-24 01:44:30
【问题描述】:
我在 listview 上使用计时器时遇到问题。
在我使用 sqlite 值显示的列表项中。有一个textview 显示数据的最后更新时间和当前时间的时间差。我必须每一秒都显示出来。这样用户就可以知道他更新了多长时间。
我尝试了多种方式。
第一种方式
我尝试在adapter 类中添加计时器。所以为每个项目创建新的计时器。所以应用程序崩溃了,因为许多计时器同时运行。
第二种方式
我尝试使用 adapter.notifyDataSetChanged() 方式。像这样。
Handler timerHandler = new Handler();
Runnable timerRunnable = new Runnable() {
@Override
public void run() {
if (adapterChatThread != null) {
adapter.notifyDataSetChanged();
}
timerHandler.postDelayed(this, 1000); // run every second
}
};
timerRunnable.run();
当点击列表项时,我移动到另一个活动,用户可以回到这个Activity。
所以在 Onresume 中我使用了
timerHandler.postDelayed(timerRunnable, 500);
和 OnPause
timerHandler.removeCallbacks(timerRunnable);
问题是数据显示不佳。我的意思是每一秒的数据差异不是一秒。一些时间差是 2 秒、5 秒、.. 等等。
表示计时器没有按预期工作。
第三条路
我使用了一个异步任务,并使用计时器每秒调用它。
class ThreadTimer extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
return null;
}
@Override
protected void onPostExecute(Void result) {
if (adapter != null)
adapter.notifyDataSetChanged();
super.onPostExecute(result);
}
}
我在这里这样称呼它
Handler timerHandler = new Handler();
Runnable timerRunnable = new Runnable() {
@Override
public void run() {
new ThreadTimer().execute();
timerHandler.postDelayed(this, 1000); // run every second
}
};
timerRunnable.run();
上一个问题已触发。 (数据显示不好)
第四条路
这样使用AsyncTask
class ThreadTimer extends AsyncTask<Void, Void, Void> {
void Sleep(int ms) {
try {
Thread.sleep(ms);
} catch (Exception e) {
}
}
@Override
protected Void doInBackground(Void... params) {
while (threadRun) {
Sleep(1000);
return null;
}
return null;
}
@Override
protected void onPostExecute(Void result) {
adapter.notifyDataSetChanged();
super.onPostExecute(result);
}
}
我在 OnResume 中调用了这个类。 在暂停时我设置 threadRun= false;
问题是一样的。
请帮帮我。
我的要求是每秒更新列表项。
谢谢。
编辑
这是我的适配器类 textview 更新代码。
Date lastUpdatedTime;
final ChatThreadDAO ctd = new ChatThreadDAO();
long timeForNextResponse = ctd.getLastRespondedTime(vct.get(position).getThread_id());
try {
if (vct.get(position).getThread_read_status() == 1 && timeForNextResponse > 0) {
final long respTime = timeForNextResponse;
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
lastUpdatedTime = formatter.parse(vct.get(position).getLast_updated_time());
final long timeDiff = (new Date()).getTime() - lastUpdatedTime.getTime();
if (timeDiff <= respTime) {
timeForNextResponse = respTime - timeDiff;
ctd.updateTimeRespondToLastMsg(vct.get(position).getThread_id(), timeForNextResponse);
holder.tvChatTimer.setVisibility(View.VISIBLE);
holder.tvChatTimer.setText(timeForNextResponse / 1000 + "");
} else {
ctd.updateTimeRespondToLastMsg(vct.get(position).getThread_id(), 0);
}
} else {
holder.tvChatTimer.setVisibility(View.INVISIBLE);
}
} catch (ParseException e) {
e.printStackTrace();
}
这里是 vct
矢量vct;
我将值分配给适配器类构造函数中的向量。
【问题讨论】:
-
等等,你是在修改适配器中的数据吗?
-
lastUpdatedTime 必须在您的适配器之外设置,适配器用于处理您的每一行,因此即使它可能工作,您仍然会在每次创建或修改列表视图的一行时设置您的 lastUpdatedTime。每当您更改矢量的内容或通知适配器刷新时,都必须设置 lastUpdatedTime。
-
非常感谢您。我删除了适配器类中的更新 lastUpdatedTime,它现在可以正常工作了。非常感谢。
-
当我不滚动它时它起作用了。但是当滚动列表时它显示不正确的值。还有其他方法可以实现吗?
-
好吧,我无法用您当前的代码来判断,但请记住,您的行是在 GetView() 方法上创建/修改的。因此,您需要在此处进行一些修改,否则您的数组中的数据可能不正确。您可以检查您的数组是否包含正确的值。每次您根据数组滚动时,默认自定义适配器都会创建一行,但大多数时候您会修改它,以便它重新使用自己。但无论哪种方式,您的 get 视图都会调用。
标签: android listview timer android-asynctask