2016-07-29 15 views

答えて

4

これは私がかなり多く考えていた問題です。

  • 新しいデータのリストをアダプタに渡し、変更された内容を確認して正しい項目を更新する作業を行います。
  • モデルに現在のアイテムを記録してから、新しいリストが計算されたらListChangeItemをアダプタに送信します。

ここでは、両方をさらに詳しく説明します。どちらの場合も、現在表示されている内容と新しいデータとの違いを計算する必要があります。これはあなたがデータクラスのequals()方法は、適切な方法で物事を比較していることを確認する必要が正しく動作するために

public class ListDiffHelper<T> { 

    private List<T> oldList; 
    private List<T> newList; 

    private List<Integer> inserted = new ArrayList<>(); 
    private List<Integer> removed = new ArrayList<>(); 

    public List<Integer> getInserted() {return inserted;} 
    public List<Integer> getRemoved() {return removed;} 

    public ListDiffHelper(List<T> oldList, List<T> newList) { 

     this.oldList = oldList; 
     this.newList = newList; 

     checkForNull(); 

     findInserted(); 
     findRemoved(); 
    } 

    private void checkForNull() { 

     if (oldList == null) oldList = Collections.emptyList(); 
     if (newList == null) newList = Collections.emptyList(); 
    } 

    private void findInserted() { 

     Set<T> newSet = new HashSet<>(newList); 
     newSet.removeAll(new HashSet<>(oldList)); 

     for (T item : newSet) { 
      inserted.add(newList.indexOf(item)); 
     } 

     Collections.sort(inserted, new Comparator<Integer>() { 
      @Override 
      public int compare(Integer lhs, Integer rhs) { 
       return lhs - rhs; 
      } 
     }); 
    } 

    private void findRemoved() { 

     Set<T> oldSet = new HashSet<>(oldList); 
     oldSet.removeAll(new HashSet<>(newList)); 

     for (T item : oldSet) { 
      removed.add(oldList.indexOf(item)); 
     } 

     Collections.sort(inserted, new Comparator<Integer>() { 
      @Override 
      public int compare(Integer lhs, Integer rhs) { 
       return rhs - lhs; 
      } 
     }); 
    } 
} 

:私は、この比較を行うヘルパークラスListDiffHelper<T>を持っています。

アダプタは、あなたのプレゼンターがモデルにgetData()を呼び出します(または、受信を使用している場合は、それをサブスクライブ)とList<Data>を受け取るこの場合

をリードしています。次に、このリストをsetData(data)メソッドを介してビューに渡します。このメソッドは、アダプタにリストを返します。

private void setData(List<Data> data) { 

    if (this.data == null || this.data.isEmpty() || data.isEmpty()) { 
     this.data = data; 
     adapter.notifyDataSetChanged(); 
     return; 
    } 

    ListDiffHelper<Data> diff = new ListDiffHelper<>(this.data, data); 
    this.data = data; 

    for (Integer index : diff.getRemoved()) { 
     notifyItemRemoved(index); 
    } 
    for (Integer index : diff.getInserted()) { 
     notifyItemInserted(index); 
    } 
} 

そう順序が正しく維持されることはありません新しいものを追加する前に、最初の項目を削除することが重要である:アダプタでの方法は、次のようになります。

モデルは

別のアプローチは非常に愚かアダプタを維持し、モデル層に変更されたかの計算を行うことですリード。個々の変更をビュー/アダプタに送信するためのラッパークラスが必要です。次のようなものがあります。

public class ListChangeItem { 

    private static final int INSERTED = 0; 
    private static final int REMOVED = 1; 

    private int type; 
    private int position; 
    private Data data; 

    public ListChangeItem(int type, int position, Data data) { 
     this.type = type; 
     this.position = position; 
     this.data = data; 
    } 

    public int getType() {return type;} 
    public int getPosition() {return position;} 
    public Data getData() {return data;} 
} 

これらのリストをビューインターフェイス経由でアダプタに渡します。データの順序が正しいことを確認するために、挿入前に削除を実行することも重要です。

+0

あなたの答えは私の問題の解決方法を理解していますが、私はMVP構造でそれを欲しがっています。私はあなたにいくつかの例を与えます、まさに私が欲しいものです。 – BK19

関連する問題