2015-07-09 16 views
12

Kết nối dữ liệu Android cung cấp một số giao diện dữ liệu quan sát bao gồm ObservableList. Nhưng SortedList (được giới thiệu trong phiên bản gần đây của thư viện RecyclerView) không mở rộng Danh sách nào cả.Làm thế nào để sử dụng SortedList trong RecyclerView với thư viện ràng buộc dữ liệu Android?

Tôi làm cách nào để sử dụng SortedList cho RecyclerView với thư viện ràng buộc dữ liệu Android?

+0

này không làm việc cho bạn? https://github.com/radzio/android-data-binding-recyclerview –

+0

@ Jürgen'Kashban'Wahlmann Tôi đã kiểm tra dự án đó, nhưng tiếc là không. Vì vậy, tôi cũng đã gửi một vấn đề cho auther: https://github.com/radzio/android-data-binding-recyclerview/issues/7 –

Trả lời

10

Lấy cảm hứng từ George núi, tôi đã thực hiện phiên bản của tôi về ObservableSortedList với chức năng đầy đủ từ SortedList gốc, bao gồm: cập nhật

  • hàng loạt. Chỉ cần gọi beginBatchedUpdates() và endBatchedUpdates() như của SortedList.
  • Làm mới và làm mới thông minh. Hàm gọi lại trong hàm tạo chịu trách nhiệm sắp xếp, loại bỏ và phân biệt nội dung.

Toàn mã:

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

Để hỗ trợ SortedList Khả năng quan sát trong ràng buộc dữ liệu, bạn phải tự mình thực hiện giao diện. Vì có xung đột trong API, có vẻ như bạn sẽ phải quấn nó. Một cái gì đó như thế này:

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

Bằng cách này, tôi phải từ bỏ nhiều ưu điểm khi sử dụng SortedList trực tiếp, như cập nhật hàng loạt, xóa bỏ, làm mới thông minh (tránh cập nhật nội dung không thay đổi). Tôi nghĩ đó không phải là cách tối ưu. –

+0

Bạn vẫn có thể có, nhưng truy cập chúng thông qua các phương pháp không có chữ ký xung đột. Ví dụ, thêm (T) trả về một int trong SortedList và boolean trong List. Nó sẽ chỉ mất một chút nỗ lực, nhưng bạn vẫn sẽ có thể nhận được tất cả những ưu điểm của SortedList. –

+0

@GeorgeMount có kế hoạch sửa lỗi này không? loại ngớ ngẩn mà chúng tôi không thể sử dụng 'SortedList' ra khỏi hộp với databinding, chưa kể đến bưu kiện một' SortedList' – ZakTaccardi

Các vấn đề liên quan