2016-07-29 30 views

回答

4

这是我想过的很多问题。这样做有它的两种可能的方式:

  • 传递数据的新表适配器和它的工作发生了什么变化,更新正确的项目工作。
  • 保留模型中当前项目的记录,然后在计算新列表时将ListChangeItem s发送到适配器。

我将在下面更详细地概述两者。在这两种情况下,您都需要计算当前显示内容与新数据之间的差异。我有一个辅助类ListDiffHelper<T>它做到这一点比较:

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; 
      } 
     }); 
    } 
} 

为此才能正常工作,你需要确保数据类的equals(),在适合的方式进行比较的东西。

适配器引线

在这种情况下,您的演讲呼吁模型getData()(或者,如果你使用的Rx订阅吧)和接收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