Best practices to use realm with a recycler view?

前端 未结 5 631
再見小時候
再見小時候 2020-12-04 15:54

Do you guys have any best practices regarding using realm with a recyclerview ? I know it\'s generic question but I found nothing on it on the internet. For example I run in

相关标签:
5条回答
  • 2020-12-04 16:18

    Some of the answers above include reflection, not to mention that a sectioned RecyclerView would cause complications. They also do not support adding and removing items. Here is my version of the RecyclerView Adapter that works with Realm, supports a sectioned RecyclerView, also adds and removes items at arbitrary positions if need be

    Here is our AbstractRealmAdapter that takes care of all the low level stuff, displaying headers, footers, items, loading data inside RealmResults, managing item types

    import io.realm.Realm;
    import io.realm.RealmObject;
    import io.realm.RealmResults;
    
    public abstract class AbstractRealmAdapter<T extends RealmObject, VH extends RecyclerView.ViewHolder>
            extends RecyclerView.Adapter<VH> {
    
        public static final int HEADER_COUNT = 1;
        public static final int FOOTER_COUNT = 1;
    
        //Our data source
        protected RealmResults<T> mResults;
    
        public AbstractRealmAdapter(Realm realm) {
            //load data from subclasses
            mResults = loadData(realm);
            notifyDataSetChanged();
        }
    
    
        public int getHeaderCount() {
            return hasHeader() ? HEADER_COUNT : 0;
        }
    
        public int getFooterCount() {
            return hasFooter() ? FOOTER_COUNT : 0;
        }
    
        public boolean isHeader(int position) {
            if (hasHeader()) {
                return position < HEADER_COUNT;
            } else {
                return false;
            }
        }
    
        public boolean isFooter(int position) {
            if (hasFooter()) {
                return position >= getCount() + getHeaderCount();
            } else {
                return false;
            }
        }
    
        @Override
        public long getItemId(int i) {
            return i;
        }
    
    
        @Override
        public final int getItemViewType(int position) {
            if (isHeader(position)) {
                return ItemType.HEADER.ordinal();
            } else if (isFooter(position)) {
                return ItemType.FOOTER.ordinal();
            } else {
                return ItemType.ITEM.ordinal();
            }
        }
    
        /**
         * @param position the position within our adapter inclusive of headers,items and footers
         * @return an item only if it is not a header or a footer, otherwise returns null
         */
        public T getItem(int position) {
            if (!isHeader(position) && !isFooter(position) && !mResults.isEmpty()) {
                return mResults.get(position - getHeaderCount());
            }
            return null;
        }
    
    
        @Override
        public final int getItemCount() {
            return getHeaderCount() + getCount() + getFooterCount();
        }
    
        public final int getCount() {
            return mResults.size();
        }
    
        public abstract boolean hasHeader();
    
        public abstract boolean hasFooter();
    
    
        public void setData(RealmResults<T> results) {
            mResults = results;
            notifyDataSetChanged();
        }
    
        protected abstract RealmResults<T> loadData(Realm realm);
    
        public enum ItemType {
            HEADER, ITEM, FOOTER;
        }
    }
    

    To add items by some method or remove items by swipe to delete, we have an extension in the form of AbstractMutableRealmAdapter that looks as shown below

    import android.support.v7.widget.RecyclerView;
    
    import io.realm.Realm;
    import io.realm.RealmObject;
    
    public abstract class AbstractMutableRealmAdapter<T extends RealmObject, VH extends RecyclerView.ViewHolder>
            extends AbstractRealmAdapter<T, VH> implements OnSwipeListener {
    
        private Realm realm;
    
        public AbstractMutableRealmAdapter(Realm realm) {
            //call the superclass constructor to load data from subclasses into realmresults
            super(realm);
            this.realm = realm;
        }
    
        public void add(T item, boolean update) {
            realm.beginTransaction();
            T phraseToWrite = (update == true) ? realm.copyToRealmOrUpdate(item) : realm.copyToRealm(item);
            realm.commitTransaction();
            notifyItemRangeChanged(0, mResults.size());
        }
    
        @Override
        public final void onSwipe(int position) {
            if (!isHeader(position) && !isFooter(position) && !mResults.isEmpty()) {
                int itemPosition = position - getHeaderCount();
                realm.beginTransaction();
                T item = mResults.get(itemPosition);
                item.removeFromRealm();
                realm.commitTransaction();
                notifyItemRemoved(position);
            }
        }
    
    }
    

    Notice the use of the interface OnSwipeListener which looks like this

    public interface OnSwipeListener {
        /**
         * @param position the position of the item that was swiped within the RecyclerView
         */
        void onSwipe(int position);
    }
    

    This SwipeListener is used to perform a Swipe to delete inside our TouchHelperCallback which in turn is used to delete the objects from Realm directly and looks as follows

    import android.support.v7.widget.RecyclerView;
    import android.support.v7.widget.helper.ItemTouchHelper;
    
    public class TouchHelperCallback extends ItemTouchHelper.Callback {
    
        private final OnSwipeListener mSwipeListener;
    
        public TouchHelperCallback(OnSwipeListener adapter) {
            mSwipeListener = adapter;
        }
    
        /**
         * @return false if you dont want to enable drag else return true
         */
        @Override
        public boolean isLongPressDragEnabled() {
            return false;
        }
    
        /**
         * @return true of you want to enable swipe in your RecyclerView else return false
         */
        @Override
        public boolean isItemViewSwipeEnabled() {
            return true;
        }
    
        @Override
        public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
            //We want to let the person swipe to the right on devices that run LTR and let the person swipe from right to left on devices that run RTL
            int swipeFlags = ItemTouchHelper.END;
            return makeMovementFlags(0, swipeFlags);
        }
    
        @Override
        public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder,
                              RecyclerView.ViewHolder target) {
            return false;
        }
    
        @Override
        public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
            mSwipeListener.onSwipe(viewHolder.getAdapterPosition());
        }
    }
    

    The full implementation demo is available here for review https://github.com/slidenerd/SpamWordList/tree/spamphraser_with_realmresults_base Feel free to suggest any improvements

    I replaced the notifyXXX methods with notifyDataSetChanged, RealmResults objects are live objects which means they automatically change when the data is updated, I tried calling notifyXXX methods and they caused an RecyclerView inconsistency exception, I am well aware of the fact that notifyDataSetChanged() would mess with animations, will keep you guys updated on a solution that overcomes the inconsistency error and at the same time provides a good adapter experience

    0 讨论(0)
  • 2020-12-04 16:29

    Implementing the Realm Add-on from Thorben Primke is a very convenient method for handling Recycler View applications with Realm databases. His github has good examples of the ways that it can be implemented.

    I'll include mine here so you have an example. First modify your project build gradle for jitpack.io:

    allprojects {
    repositories {
        jcenter()
        maven { url "https://jitpack.io" }
    }
    

    Then your module gradle to point to the library: (note , check for latest version)

    dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile 'com.github.thorbenprimke:realm-recyclerview:0.9.20'
    

    Create the xml layout for a recycler view using the RealmRecyclerView:

        <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
    
        android:id="@+id/swipeRefreshLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    
        <co.moonmonkeylabs.realmrecyclerview.RealmRecyclerView
            android:id="@+id/realm_recycle_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:rrvIsRefreshable="true"
            app:rrvEmptyLayoutId="@layout/empty_view"
            app:rrvLayoutType="LinearLayout"
            app:rrvSwipeToDelete="true"
            />
    </RelativeLayout>
    

    Now in your RealmRecycler Fragment obtain a Realm query result of RealmObjects, inflate and define a Primke RealmAdapter:

     Log.i(TAG, " Obtain Filtered List");
        final RealmResults <Session> realmResults = queryD.findAllSorted(
                "sessionId", Sort.DESCENDING);
    
        Log.i(TAG, " Inflate realm List");
        View view = inflater.inflate(R.layout.realm_card_recycler2, null);
    
        Log.i(TAG, " Define and configure SessionRealmAdapter");
        SessionRealmAdapter sessionRealmAdapter =
                new SessionRealmAdapter(getActivity(), realmResults, true,    true);`enter code here`
        RealmRecyclerView realmRecyclerView =
                (RealmRecyclerView)  view.findViewById(R.id.realm_recycle_view);
        realmRecyclerView.setAdapter(sessionRealmAdapter);
    

    Finally configure the Realm Adapter for whatever you want for actions. I've got a couple for clicks and turned on the swipe to delete for deleting realm records.

          public class SessionRealmAdapter
              extends RealmBasedRecyclerViewAdapter<Session, SessionRealmAdapter.ViewHolder> {
    
          public class ViewHolder extends RealmViewHolder {
    
              public TextView sessionTextView;
              public ViewHolder(FrameLayout container) {
                  super(container);
                  this.sessionTextView = (TextView) container.findViewById(R.id.session_text_view);
              }
          }
    
          public SessionRealmAdapter(
                  Context context,
                  RealmResults<Session> realmResults,
                  boolean automaticUpdate,
                  boolean animateResults) {
              super(context, realmResults, automaticUpdate, animateResults);
          }
    
          @Override
          public ViewHolder onCreateRealmViewHolder(ViewGroup viewGroup, int viewType) {
              View v = inflater.inflate(R.layout.session_simple_view, viewGroup, false);
              return new ViewHolder((FrameLayout) v);
          }
    
          @Override
          public void onBindRealmViewHolder(ViewHolder viewHolder, int position) {
              final Session singleSession = realmResults.get(position);
              viewHolder.sessionTextView.setText(singleSession.gettMethod());
              viewHolder.sessionTextView.setOnClickListener(
                      new View.OnClickListener(){
    
                          @Override
                          public void onClick(View v){
                              selectSession(singleSession);
                              showMessage(" Selected "+singleSession.gettMethod());
                          }
                      }
              );
              viewHolder.sessionTextView.setOnLongClickListener(
                      new View.OnLongClickListener(){
    
                          @Override
                          public boolean onLongClick(View v){
                                showInformationDialog(singleSession);
                                showMessage("Long click selected for "
                                        +singleSession.getSessionTitle());
                                return true;
                          }
                      }
              );
          }
      }
    
    0 讨论(0)
  • 2020-12-04 16:31

    Your post does not even contain a real question.

    Have you checked out this post: http://gradlewhy.ghost.io/realm-results-with-recyclerview/ ?

    Not sure why you wouldn't just use an ArrayList in your adapter and add all elements from the RealmResult to that list though. Could anyone explain why the solution in the blog post would be better?

    0 讨论(0)
  • 2020-12-04 16:37

    ANSWER FOR 0.89.0 AND ABOVE

    For the latest versions, you should use RealmRecyclerViewAdapter in the realm-android-adapters repository.

    Versions:

    • Use 1.5.0 up to 2.X

    • Use 2.1.1 up to 4.X

    • Use 3.0.0 above 5.X


    OLD ANSWER FOR OLD VERSIONS:

    I made this RealmRecyclerViewAdapter based on the implementation of RealmBaseAdapter.

    This is for v0.89.0 AND ABOVE

    public abstract class RealmRecyclerViewAdapter<T extends RealmObject, VH extends RecyclerView.ViewHolder>
        extends RecyclerView.Adapter<VH> { //put this in `io.realm`
    
        protected LayoutInflater inflater;
        protected OrderedRealmCollection<T> adapterData;
        protected Context context;
        private final RealmChangeListener listener;
    
        public RealmRecyclerViewAdapter(Context context, OrderedRealmCollection<T> data) {
            if (context == null) {
                throw new IllegalArgumentException("Context cannot be null");
            }
            this.context = context;
            this.adapterData = data;
            this.inflater = LayoutInflater.from(context);
            this.listener = new RealmChangeListener<RealmResults<T>>() {
                @Override
                public void onChange(RealmResults<T> results) {
                    notifyDataSetChanged();
                }
            };
    
            if (data != null) {
                addListener(data);
            }
        }
    
        private void addListener(OrderedRealmCollection<T> data) {
            if (data instanceof RealmResults) {
                RealmResults realmResults = (RealmResults) data;
                realmResults.addChangeListener(listener);
            } else if (data instanceof RealmList) {
                RealmList realmList = (RealmList) data;
                realmList.realm.handlerController.addChangeListenerAsWeakReference(listener);
            } else {
                throw new IllegalArgumentException("RealmCollection not supported: " + data.getClass());
            }
        }
    
        private void removeListener(OrderedRealmCollection<T> data) {
            if (data instanceof RealmResults) {
                RealmResults realmResults = (RealmResults) data;
                realmResults.removeChangeListener(listener);
            } else if (data instanceof RealmList) {
                RealmList realmList = (RealmList) data;
                realmList.realm.handlerController.removeWeakChangeListener(listener);
            } else {
                throw new IllegalArgumentException("RealmCollection not supported: " + data.getClass());
            }
        }
    
        /**
         * Returns how many items are in the data set.
         *
         * @return the number of items.
         */
        @Override
        public int getItemCount() {
            if (adapterData == null) {
                return 0;
            }
            return adapterData.size();
        }
    
        /**
         * Get the data item associated with the specified position in the data set.
         *
         * @param position Position of the item whose data we want within the adapter's
         * data set.
         * @return The data at the specified position.
         */
        public T getItem(int position) {
            if (adapterData == null) {
                return null;
            }
            return adapterData.get(position);
        }
    
        /**
         * Get the row id associated with the specified position in the list. Note that item IDs are not stable so you
         * cannot rely on the item ID being the same after {@link #notifyDataSetChanged()} or
         * {@link #updateData(OrderedRealmCollection)} has been called.
         *
         * @param position The position of the item within the adapter's data set whose row id we want.
         * @return The id of the item at the specified position.
         */
        @Override
        public long getItemId(int position) {
            // TODO: find better solution once we have unique IDs
            return position;
        }
    
        /**
         * Updates the data associated with the Adapter.
         *
         * Note that RealmResults and RealmLists are "live" views, so they will automatically be updated to reflect the
         * latest changes. This will also trigger {@code notifyDataSetChanged()} to be called on the adapter.
         *
         * This method is therefore only useful if you want to display data based on a new query without replacing the
         * adapter.
         *
         * @param data the new {@link OrderedRealmCollection} to display.
         */
        public void updateData(OrderedRealmCollection<T> data) {
            if (listener != null) {
                if (adapterData != null) {
                    removeListener(adapterData);
                }
                if (data != null) {
                    addListener(data);
                }
            }
    
            this.adapterData = data;
            notifyDataSetChanged();
        }
    }
    

    This is for v0.84.0 AND ABOVE, BUT OLDER THAN v0.89.0 (updated for v0.87.5):

    public abstract class RealmRecyclerViewAdapter<T extends RealmObject, VH extends RecyclerView.ViewHolder>
            extends RecyclerView.Adapter<VH> { //put this in `io.realm`
        protected LayoutInflater inflater;
        protected RealmResults<T> realmResults;
        protected Context context;
        private final RealmChangeListener listener;
    
        public RealmRecyclerViewAdapter(Context context, RealmResults<T> realmResults, boolean automaticUpdate) {
            if (context == null) {
                throw new IllegalArgumentException("Context cannot be null");
            }
            this.context = context;
            this.realmResults = realmResults;
            this.inflater = LayoutInflater.from(context);
            this.listener = (!automaticUpdate) ? null : new RealmChangeListener() {
                @Override
                public void onChange() {
                    notifyDataSetChanged();
                }
            };
    
            if (listener != null && realmResults != null) {
                realmResults.realm.handlerController.addChangeListenerAsWeakReference(listener);
            }
        }
    
        /**
         * Returns how many items are in the data set.
         *
         * @return count of items.
         */
        @Override
        public int getItemCount() {
            if (realmResults == null) {
                return 0;
            }
            return realmResults.size();
        }
    
        /**
         * Returns the item associated with the specified position.
         *
         * @param i index of item whose data we want.
         * @return the item at the specified position.
         */
        public T getItem(int i) {
            if (realmResults == null) {
                return null;
            }
            return realmResults.get(i);
        }
    
        /**
         * Returns the current ID for an item. Note that item IDs are not stable so you cannot rely on the item ID being the
         * same after {@link #notifyDataSetChanged()} or {@link #updateRealmResults(RealmResults)} has been called.
         *
         * @param i index of item in the adapter.
         * @return current item ID.
         */
        @Override
        public long getItemId(int i) {
            // TODO: find better solution once we have unique IDs
            return i;
        }
    
        /**
         * Updates the RealmResults associated to the Adapter. Useful when the query has been changed.
         * If the query does not change you might consider using the automaticUpdate feature.
         *
         * @param queryResults the new RealmResults coming from the new query.
         */
        public void updateRealmResults(RealmResults<T> queryResults) {
            if (listener != null) {
                // Making sure that Adapter is refreshed correctly if new RealmResults come from another Realm
                if (this.realmResults != null) {
                    this.realmResults.realm.removeChangeListener(listener);
                }
                if (queryResults != null) {
                    queryResults.realm.addChangeListener(listener);
                }
            }
    
            this.realmResults = queryResults;
            notifyDataSetChanged();
        }
    
        public void addChangeListenerAsWeakReference(RealmChangeListener realmChangeListener) {
            if(realmResults != null) {
                realmResults.realm.handlerController.addChangeListenerAsWeakReference(realmChangeListener);
            }
        }
    }
    

    This is for OLDER THAN 0.84.0:

    public abstract class RealmRecyclerViewAdapter<T extends RealmObject, VH extends RecyclerView.ViewHolder>
            extends RecyclerView.Adapter<VH> { //put this in `io.realm`
        protected LayoutInflater inflater;
        protected RealmResults<T> realmResults;
        protected Context context;
    
        private final RealmChangeListener listener;
    
        public RealmRecyclerViewAdapter(Context context, RealmResults<T> realmResults, boolean automaticUpdate) {
            if(context == null) {
                throw new IllegalArgumentException("Context cannot be null");
            }
            this.context = context;
            this.realmResults = realmResults;
            this.inflater = LayoutInflater.from(context);
            this.listener = (!automaticUpdate) ? null : new RealmChangeListener() {
                @Override
                public void onChange() {
                    notifyDataSetChanged();
                }
            };
    
            if(listener != null && realmResults != null) {
                realmResults.getRealm()
                        .addChangeListener(listener);
            }
        }
    
        @Override
        public long getItemId(int i) {
            // TODO: find better solution once we have unique IDs
            return i;
        }
    
        public T getItem(int i) {
            if(realmResults == null) {
                return null;
            }
            return realmResults.get(i);
        }
    
        public void updateRealmResults(RealmResults<T> queryResults) {
            if(listener != null) {
                // Making sure that Adapter is refreshed correctly if new RealmResults come from another Realm
                if(this.realmResults != null) {
                    realmResults.getRealm().removeChangeListener(listener);
                }
                if(queryResults != null) {
                    queryResults.getRealm().addChangeListener(listener);
                }
            }
    
            this.realmResults = queryResults;
            notifyDataSetChanged();
        }
    
        @Override
        public int getItemCount() {
            if(realmResults == null) {
                return 0;
            }
            return realmResults.size();
        }
    }
    
    0 讨论(0)
  • 2020-12-04 16:39

    Now that with Realm 0.88.2 we can make a RecyclerView adapter that updates the RecyclerView with more precision than using notifyDataSetChanged() every time. This can be accomplished by using the new ability create custom methods.

    Overriding the equals method, in the realm object that will be used with the recycler adapter, is all that will be needed. (You don't actually need to override equals... but you may find that realm objects do not equal each other when you expect them to. This will lead to unnecessary recyclerview updates after running diff)

    Then add Google's java-diff-utils to your gradle dependencies

        compile 'com.googlecode.java-diff-utils:diffutils:1.3.0'
    

    Using this RealmRecyclerViewAdapter implementation a copy of realmResults is made at start, and on every change to compare against future changes. Detected changes are used to update the RecyclerView as appropriate

    public abstract class RealmRecyclerViewAdapter<T extends RealmObject, VH extends RecyclerView.ViewHolder>
        extends RecyclerView.Adapter<VH> {
    
    
    protected RealmResults<T> realmResults;
    protected List<T> lastCopyOfRealmResults;
    int maxDepth = 0;
    
    private RealmChangeListener realmResultsListener;
    Realm realm;
    
    public RealmRecyclerViewAdapter(RealmResults<T> realmResults, boolean automaticUpdate) {
        this(realmResults, automaticUpdate, 0);
    }
    
    /**
     *
     * @param realmResults
     * @param automaticUpdate
     * @param maxDepth limit of the deep copy when copying realmResults. All references after this depth will be {@code null}. Starting depth is {@code 0}.
     *                 A copy of realmResults is made at start, and on every change to compare against future changes. Detected changes are used to update
     *                 the RecyclerView as appropriate
     */
    public RealmRecyclerViewAdapter(RealmResults<T> realmResults, boolean automaticUpdate, int maxDepth) {
    
        this.realmResultsListener = (!automaticUpdate) ? null : getRealmResultsChangeListener();
    
        if (realmResultsListener != null && realmResults != null) {
            realmResults.addChangeListener(realmResultsListener);
        }
        this.realmResults = realmResults;
        realm = Realm.getDefaultInstance();
        this.maxDepth = maxDepth;
    
        lastCopyOfRealmResults = realm.copyFromRealm(realmResults, this.maxDepth);
    }
    
    
    
    @Override
    public int getItemCount() {
        return realmResults != null ? realmResults.size() : 0;
    }
    
    /**
     * Make sure this is called before a view is destroyed to avoid memory leaks do to the listeners.
     * Do this by calling setAdapter(null) on your RecyclerView
     * @param recyclerView
     */
    @Override
    public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
        super.onDetachedFromRecyclerView(recyclerView);
        if (realmResultsListener != null) {
            if (realmResults != null) {
                realmResults.removeChangeListener(realmResultsListener);
            }
        }
        realm.close();
    }
    
    /**
     * Update the RealmResults associated with the Adapter. Useful when the query has been changed.
     * If the query does not change you might consider using the automaticUpdate feature.
     *
     * @param queryResults the new RealmResults coming from the new query.
     * @param maxDepth limit of the deep copy when copying realmResults. All references after this depth will be {@code null}. Starting depth is {@code 0}.
     *                 A copy of realmResults is made at start, and on every change to compare against future changes. Detected changes are used to update
     *                 the RecyclerView as appropriate
     */
    public void updateRealmResults(RealmResults<T> queryResults, int maxDepth) {
        if (realmResultsListener != null) {
            if (realmResults != null) {
                realmResults.removeChangeListener(realmResultsListener);
            }
        }
    
        realmResults = queryResults;
        if (realmResults != null && realmResultsListener !=null) {
            realmResults.addChangeListener(realmResultsListener);
        }
        this.maxDepth = maxDepth;
        lastCopyOfRealmResults = realm.copyFromRealm(realmResults,this.maxDepth);
    
        notifyDataSetChanged();
    }
    
    public T getItem(int position) {
        return realmResults.get(position);
    }
    
    public int getRealmResultsSize(){
        return realmResults.size();
    }
    
    
    private RealmChangeListener getRealmResultsChangeListener() {
        return new RealmChangeListener<RealmResults<T>>() {
            @Override
            public void onChange(RealmResults<T> element) {
                if (lastCopyOfRealmResults != null && !lastCopyOfRealmResults.isEmpty()) {
                    if (realmResults.isEmpty()) {
                        // If the list is now empty, just notify the recyclerView of the change.
                        lastCopyOfRealmResults = realm.copyFromRealm(realmResults,maxDepth);
                        notifyDataSetChanged();
                        return;
                    }
                    Patch patch = DiffUtils.diff(lastCopyOfRealmResults, realmResults);
                    List<Delta> deltas = patch.getDeltas();
                    lastCopyOfRealmResults = realm.copyFromRealm(realmResults,maxDepth);
                    if (!deltas.isEmpty()) {
                        List<Delta> deleteDeltas = new ArrayList<>();
                        List<Delta> insertDeltas = new ArrayList<>();
                        for (final Delta delta : deltas) {
                            switch (delta.getType()){
                                case DELETE:
                                    deleteDeltas.add(delta);
                                    break;
                                case INSERT:
                                    insertDeltas.add(delta);
                                    break;
                                case CHANGE:
                                    notifyItemRangeChanged(
                                            delta.getRevised().getPosition(),
                                            delta.getRevised().size());
                                    break;
                            }
                        }
                        for (final Delta delta : deleteDeltas) {
                            notifyItemRangeRemoved(
                                    delta.getOriginal().getPosition(),
                                    delta.getOriginal().size());
                        }
                        //item's should be removed before insertions are performed
                        for (final Delta delta : insertDeltas) {
                            notifyItemRangeInserted(
                                    delta.getRevised().getPosition(),
                                    delta.getRevised().size());
                        }
                    }
                } else {
                    notifyDataSetChanged();
                    lastCopyOfRealmResults = realm.copyFromRealm(realmResults,maxDepth);
                }
            }
        };
    }
    
    }
    
    0 讨论(0)
提交回复
热议问题