2015-07-09 15 views
12

Wiązanie danych Androida zapewnia kilka możliwych do zaobserwowania interfejsów danych, w tym ObservableList. Ale SortedList (wprowadzone w najnowszej wersji biblioteki RecyclerView) w ogóle nie rozszerza Listy.Jak korzystać z SortedList w RecyclerView z biblioteką powiązań danych Androida?

Jak używać SortedList dla RecyclerView z biblioteką danych Androida?

+0

ta nie działa dla Ciebie? https://github.com/radzio/android-data-binding-recyclerview –

+0

@ Jürgen'Kashban'Wahlmann Już sprawdziłem ten projekt, ale niestety nie. Więc też zgłosiłem problem dla authera: https://github.com/radzio/android-data-binding-recyclerview/issues/7 –

Odpowiedz

10

Zainspirowany George Górze I wprowadziły moja wersja ObservableSortedList pełną funkcjonalność z oryginalnym SortedList, w tym: Aktualizacja

  • partii. Wystarczy wywołać beginBatchedUpdates() i endBatchedUpdates() jak z SortedList.
  • De-dup i inteligentne odświeżanie. Callback w konstruktorze jest odpowiedzialny za porządkowanie, usuwanie duplikatów i różnicowanie treści.

Pełny kod:

public class ObservableSortedList<T> extends AbstractList<T> implements ObservableList<T> { 

    /** @see android.support.v7.util.SortedList.Callback */ 
    public interface Callback<T2> { 
    /** @see android.support.v7.util.SortedList.Callback#compare(Object, Object) */ 
    int compare(T2 o1, T2 o2); 
    /** @see android.support.v7.util.SortedList.Callback#areItemsTheSame(Object, Object) */ 
    boolean areItemsTheSame(T2 item1, T2 item2); 
    /** @see android.support.v7.util.SortedList.Callback#areContentsTheSame(Object, Object) */ 
    boolean areContentsTheSame(T2 oldItem, T2 newItem); 
    } 

    public ObservableSortedList(final Class<T> klass, final Callback<T> callback) { 
    mList = new SortedList<>(klass, new CallbackWrapper<>(callback)); 
    } 

    /** @see SortedList#beginBatchedUpdates() */ 
    public void beginBatchedUpdates() { mList.beginBatchedUpdates(); } 
    /** @see SortedList#endBatchedUpdates() */ 
    public void endBatchedUpdates() { mList.endBatchedUpdates(); } 

    @Override public boolean add(final T item) { 
    sTlsUpdated.set(false); 
    mList.add(item); 
    return sTlsUpdated.get(); // May be set by Callback.onInserted() or onChanged(). 
    } 

    @Override public T set(final int location, final T object) { 
    final T old = mList.get(location); 
    mList.updateItemAt(location, cast(object)); 
    return old; 
    } 

    @Override public int indexOf(final Object object) { 
    try { 
     return mList.indexOf(cast(object)); 
    } catch (final ClassCastException ignored) { 
     return -1; 
    } 
    } 

    @Override public boolean remove(final Object object) { 
    try { 
     return mList.remove(cast(object)); 
    } catch (final ClassCastException ignored) { 
     return false; 
    } 
    } 

    @SuppressWarnings("unchecked") private T cast(final Object object) { return (T) object; } 

    @Override public boolean contains(final Object object) { return indexOf(object) != SortedList.INVALID_POSITION; } 
    @Override public T get(final int location) { return mList.get(location); } 
    @Override public int size() { return mList.size(); } 
    @Override public void clear() { mList.clear(); } 
    @Override public T remove(final int location) { return mList.removeItemAt(location); } 

    /* ObservableList */ 

    @Override public void addOnListChangedCallback(final OnListChangedCallback<? extends ObservableList<T>> callback) { 
    if (mListeners == null) this.mListeners = new ListChangeRegistry(); 
    mListeners.add(callback); 
    } 

    @Override public void removeOnListChangedCallback(final OnListChangedCallback<? extends ObservableList<T>> callback) { 
    if (mListeners == null) return; 
    mListeners.remove(callback); 
    } 

    private final SortedList<T> mList; 
    private static final ThreadLocal<Boolean> sTlsUpdated = new ThreadLocal<>(); 
    private transient @Nullable ListChangeRegistry mListeners = new ListChangeRegistry(); 

    public class CallbackWrapper<T2> extends SortedList.Callback<T2> { 

    @Override public final void onInserted(final int position, final int count) { 
     sTlsUpdated.set(true); 
     if (mListeners != null) mListeners.notifyInserted(ObservableSortedList.this, position, count); 
    } 

    @Override public final void onRemoved(final int position, final int count) { 
     if (mListeners != null) mListeners.notifyRemoved(ObservableSortedList.this, position, count); 
    } 

    @Override public final void onMoved(final int fromPosition, final int toPosition) { 
     if (mListeners != null) mListeners.notifyMoved(ObservableSortedList.this, fromPosition, toPosition, 1); 
    } 

    @Override public final void onChanged(final int position, final int count) { 
     sTlsUpdated.set(true); 
     if (mListeners != null) mListeners.notifyChanged(ObservableSortedList.this, position, count); 
    } 

    @Override public int compare(final T2 o1, final T2 o2) { return mCallback.compare(o1, o2); } 
    @Override public boolean areContentsTheSame(final T2 oldItem, final T2 newItem) { return mCallback.areContentsTheSame(oldItem, newItem); } 
    @Override public boolean areItemsTheSame(final T2 item1, final T2 item2) { return mCallback.areItemsTheSame(item1, item2); } 
    public CallbackWrapper(final Callback<T2> callback) { mCallback = callback; } 

    private final Callback<T2> mCallback; 
    } 
} 
8

Aby włączyć obsługę sortowania w powiązaniu danych, należy samodzielnie zaimplementować interfejs. Ponieważ w interfejsie API występuje konflikt, wydaje się, że musisz go zawinąć. Coś takiego:

public class ObservableSortedList<T> implements ObservableList<T> { 
    private final SortedList<T> mList; 
    private final ListChangeRegistry mListeners = new ListChangeRegistry(); 

    @Override 
    public boolean add(T item) { 
     int index = mList.add(item); 
     mListeners.notifyInserted(this, index, 1); 
    } 

    @Observable 
    public void addOnListChangedCallback(OnListChangedCallback<? extends ObservableList<T>> callback) { 
     mListeners.add(callback); 
    } 

    ... 
} 
+1

W ten sposób, muszę zrezygnować z wielu zalet korzystania z SortedList bezpośrednio, jak aktualizacja wsadowa, usuwanie duplikatów, inteligentne odświeżanie (unikaj odświeżania zawartości - niezmieniona aktualizacja). Myślę, że nie jest to optymalny sposób. –

+0

Nadal możesz je mieć, ale uzyskaj do nich dostęp za pomocą metod, które nie mają sprzecznych podpisów. Na przykład add (T) zwraca int w SortedList i boolean w List. Wystarczy trochę wysiłku, ale nadal będziesz w stanie uzyskać wszystkie zalety SortedList. –

+0

@GeorgeMount czy planują to naprawić? rodzaj głupiego, że nie możemy używać 'SortedList' po wyjęciu z pudełka z wiązaniem danych, nie wspominając o paczkowaniu' SortedList' – ZakTaccardi

Powiązane problemy