Android 从计时器更新库/列表视图项目视图

Android 从计时器更新库/列表视图项目视图,android,multithreading,listview,gallery,adapter,Android,Multithreading,Listview,Gallery,Adapter,我想从计时器更新UI。这根本不是问题,但当涉及到Gallery/ListView时,它会变得很困难。我有一个带有自定义BaseAdapter的图库。我需要一个计数器为每个(画廊)项目(每个项目计数不同,取决于项目数据)。该计数器应该在主线程之外运行。此外,当只有一个项目可见时,我不想为库中的10个项目运行10个线程。当项目/视图可见时,在adapters getView()方法中定义处理程序并启动线程(计数)不是问题。我可以想到如下代码: 公共类MyAdapter扩展了BaseAdapter{

我想从计时器更新UI。这根本不是问题,但当涉及到Gallery/ListView时,它会变得很困难。我有一个带有自定义BaseAdapter的图库。我需要一个计数器为每个(画廊)项目(每个项目计数不同,取决于项目数据)。该计数器应该在主线程之外运行。此外,当只有一个项目可见时,我不想为库中的10个项目运行10个线程。当项目/视图可见时,在adapters getView()方法中定义处理程序并启动线程(计数)不是问题。我可以想到如下代码:


公共类MyAdapter扩展了BaseAdapter{

    static class ViewHolder {
         //...
         public Handler myHandler;
     }

     public View getView(int position, View convertView, ViewGroup parent) {

            //...
            // getView() gets called indefinite so first remove callback because it may be added already        
            holder.myHandler.removeCallbacks(myRunnable);
            holder.myHandler.postDelayed(myRunnable, 0);

            //...
     }
}

问题是删除不再可见的视图的回调,因为在getView()中,当视图变为可见时,我会被注意到,但我不知道如何获取变为不可见的视图(以及持有人及其处理程序)来删除回调

有(其他)方法解决这个问题吗?

找到了一个干净的解决方案(如果有人需要这样的解决方案)。我需要更新一个TextView来设置新的计数器值(每秒)

在BaseAdapters getView中,我将文本视图添加到WeakHashMap。文本视图是地图的关键。如果不再引用键,则将删除键/值映射。所以我不会导致内存泄漏。垃圾收集工做这项工作

一个线程对“计数器对象”进行计数,并用相应的值刷新文本视图(GarbageCollector一直运行,因此在我的例子中,地图主要由3个项目组成,因为图库只显示一个项目。由于GarbageCollection,地图立即被“未使用”清除文本视图(特别是在快速滚动列表/图库时)

BaseAdapter的getView():


恭喜你成功了。如果您有能力,请将您的答案标记为“已接受”,以帮助他人找到您的解决方案。干杯~
private WeakHashMap<TextView, Integer> counterMap = new WeakHashMap<TextView,Integer>();
private Handler counterHandler = new Handler();

public View getView(...) {
    //...
    counterMap.put(holder.tvCounter, position);
    //...
}
// Thread decrementing the time of the counter objects and updating the UI
private final Runnable counterTimeTask = new Runnable() {
    public void run() {
        //...
        // decrement the remaining time of all objects
        for (CounterData data : counterDataList) 
            data.decrementTimeLeftInSeconds();

        // iterate through the map and update the containing TextViews
        for (Map.Entry<TextView, Integer> entry : counterMap.entrySet()) {
            TextView tvCounter = entry.getKey();
            Integer position = entry.getValue();
            CounterData data = counterDataList.get(position);
            long timeLeftInSeconds = data.getTimeLeftInSeconds();
            tvCounter.setText(" " + timeLeftInSeconds);
        }

        if (yourCondition)
            counterHandler.postDelayed(this, 1000);
    }
};
public void startCounter() { counterHandler.post(counterTimeTask); }
public void stopCounter() { counterHandler.removeCallbacks(counterTimeTask); }