Android:每1分钟更新一次ListView项目

我在我的应用程序中有一个自定义ListView,包含一个ImageView和3-5个TextViews。

1的TextViews显示当前时间和为该ListView项目指定的时间之间的时间差距。

喜欢: 5分钟前发布

问题是,我怎样才能更新这个TextView每分钟没有任何干扰的ListView。

喜欢: 如果我在看ListView 5分钟,只是这个TextView单独必须从1分钟改变为2分钟等等每个项目可见

我试过了:

  1. 使用System.currentTimeMillis() - givenTime[position];设置此TextView在getView()中 System.currentTimeMillis() - givenTime[position];

但在这里TextView不会得到更新,如果我不滚动(不调用getView)或更改项目的可见性。

  1. 每1分钟使用一个timeTask()线程,并尝试更新每个项目的TextView

这里的问题是我得到一个例外:

 android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 

此外,我不知道如何更改每个活动的ListView项的TextView。

但是,这看起来像一个熟悉的情况。

我怎么能做到这一点?

谢谢

使用Handler及其postDelayed方法使列表的适配器失效,如下所示:

 final Handler handler = new Handler() handler.postDelayed( new Runnable() { @Override public void run() { adapter.notifyDataSetChanged(); handler.postDelayed( this, 60 * 1000 ); } }, 60 * 1000 ); 

您只能在主(UI)线程中更新UI。

通过在主线程中创build处理程序,确保您发布到处理程序的所有内容都在主线程中运行。

你也可以创build自定义的TextView ,每秒或每分钟或每小时更新一次。 这可以通过创build扩展TextView并在该类中添加Handler来轻松完成。 好处是你不必更新你的整个ListView,TextView会自动更新自己。

例:

 public class TextViewTimeCounter extends TextView { private long mStartTime = 0; private long mTimeNow = 0; private int mDelay = 0; private String mPart1 = ""; private String mPart2 = ""; private Handler mHandler; public TextViewTimeCounter(Context context) { super(context, null, 0); } public TextViewTimeCounter(Context context, AttributeSet attrs) { this(context, attrs, 0); } public TextViewTimeCounter(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public void startTimer(long delay, String part1, String part2){ mStartTime = System.currentTimeMillis(); mTimeNow = System.currentTimeMillis(); mDelay = delay; mHandler = new Handler(); mHandler.postDelayed(r, delay); convertDatesToMinutes(mStartTime, mTimeNow); } public void stopTimer(){ if(mHandler != null){ mHandler = null; mStartTime = 0; mTimeNow = 0; } } public boolean isTimerRunning(){ return mHandler == null? false : true; } Runnable r = new Runnable() { @Override public void run(){ mTimeNow += mDelay; convertDatesToMinutes(mStartTime, mTimeNow); if(mHandler != null){ mHandler.postDelayed(r, mDelay); } } }; public void convertDatesToMinutes(long start, long end){ long secs = (end - start); long minute = (secs / (1000 * 60)) % 60; long hour = (secs / (1000 * 60 * 60)) % 24; String time = String.format(Locale.getDefault(), "%2d hours %2d minutes", hour, minute); setText(mPart1 + time + mPart2); } 

用法:

 TextViewTimeCounter timer = (TextViewTimeCounter)convertView.findViewById(R.id.start_logging_time_text); timer.startTimer(10000, "Posted ", " ago"); 

输出将如下所示:

  Posted 1 hours 5 minutes ago 

如果你想显示秒,也可以将convertDatesToMinutes(long start, long end)方法更改为:

 public void convertDatesToMinutes(long start, long end){ long secs = (end - start); long second = (secs / 1000) % 60; long minute = (secs / (1000 * 60)) % 60; long hour = (secs / (1000 * 60 * 60)) % 24; String time = String.format(Locale.getDefault(), "%2d hours %2d minutes %2d seconds", hour, minute, second); setText(mPart1 + time + mPart2); } 

使用内置的TimerTask

http://developer.android.com/reference/java/util/TimerTask.html

这是一个坚实的做事方式。

如果你想在一小段时间内在主线程中重复一个动作,你应该使用Time.class的“schedule”方法

 mHandler = new Handler(); mTimer = new Timer(); mTimer.schedule(new TimerTask() { @Override public void run() { mHandler.post(new Runnable() { @Override public void run() { // run main thread code } }); } }, DELAY_TIME, PERIOD_TIME);