2012-03-08 10 views
0

タイマーからUIを更新したいと思います。それはまったく問題ではありませんが、Gallery/ListViewsに関しては難しくなります。カスタムBaseAdapterを持つギャラリーがあります。私はすべての(ギャラリー)アイテム(すべてのアイテムはアイテムデータによって異なる)にカウンタが必要です。そのカウンタはメインスレッドの外側で実行する必要があります。さらに、1つの項目だけが表示されている場合、ギャラリーの10項目に対して10のスレッドを実行する必要はありません。 ItemViewが表示されたときにHandlerを定義し、アダプターgetView()メソッドでスレッド(カウント)を開始することは問題ではありません。 getViewメソッド()で、私はビューが表示されたときに気づかので更新ギャラリー/リストビューアイテムビューからタイマー

public class MyAdapter extends 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); 

      //... 
    } 

}

問題はもう見えないビューのthatsのためのコールバックを削除することですが、私は何を持っている:私は、次のコードのようなものを考えることはできませんどのようにコールバックを取り除くことが不可視になったのか(したがってホルダーとそのハンドラー)のビューを取得する方法を手がかりにします。

これを解決するアプローチがありますか?

答えて

2

清潔な解決策が見つかった場合(そのようなものが必要な場合)新しいカウンタ値(毎秒)を設定するためにTextViewを更新する必要がありました。

BaseAdapter getViewでは、WeakHashMapにTextViewを追加します。 TextViewはマップのキーです。キーが参照されなくなった場合、キー/値のマッピングが削除されます。だから私はメモリリークを引き起こしません。 GarbageCollectorが処理を行います。

スレッドは「カウンターオブジェクト」をカウントダウンし、TextViewsを対応する値でリフレッシュします(GarbageCollectorは常に実行されます。私の場合、ギャラリーは1つのアイテムしか表示しないため、

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); 
    } 
}; 
すぐに特別にリスト/ギャラリーを高速でスクロールする "未使用" TextViews)

BaseAdapterのgetViewメソッド()によってクリアされます

スタート/カウンタを停止します。修正に

public void startCounter() { counterHandler.post(counterTimeTask); } 
public void stopCounter() { counterHandler.removeCallbacks(counterTimeTask); } 
+0

おめでとう。あなたができるときは、他の人があなたの解決策を見つけるのを助けるためにあなたの答えを「受け入れられた」とマークしてください。乾杯〜 –

関連する問題