简体   繁体   中英

How to save and restore RecyclerView Items's positions using Json

I have a RecyclerView with 5 items and drag & drop feature. I want to save items's positions into SharedPreferences in order to restore them when the App is launched. Currently I'm able to save their positions into SharedPreferences using Json but the App crashes when I restore positions. Any solution? Thanks.

    public static AppCompatActivity mActivity;
    public static SharedPreferences SP;
    public static SharedPreferences.Editor mEditor;
    public static RecyclerView mRecyclerView;
    public static RecyclerViewDragDropManager mRecyclerViewDragDropManager;
    public static List<Long> mSaveItemsOrder;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        mActivity = this;

        SP = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
        mEditor = SP.edit();

        mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        mRecyclerViewDragDropManager = new RecyclerViewDragDropManager();
        mRecyclerViewDragDropManager.setInitiateOnMove(false);
        mRecyclerViewDragDropManager.setInitiateOnLongPress(true);
        mRecyclerViewDragDropManager.setLongPressTimeout(300);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mRecyclerView.setAdapter(mRecyclerViewDragDropManager.createWrappedAdapter(new Adapter()));
        mRecyclerViewDragDropManager.attachRecyclerView(mRecyclerView);
    }

    public static class Item {
        public final long id;
        public final String text;

        public Item(long id, String text) {
            this.id = id;
            this.text = text;
        }
    }

    public static class ViewHolder extends AbstractDraggableItemViewHolder {

        Button mButton;

        public ViewHolder(View itemView) {
            super(itemView);
            mButton = (Button) itemView.findViewById(R.id.button);
        }

    }

    public static class Adapter extends RecyclerView.Adapter<ViewHolder> implements DraggableItemAdapter<ViewHolder> {

        List<Item> mItems;

        public Adapter() {
            setHasStableIds(true);

            mItems = new ArrayList<>();
            if (SP.getString("items_order", null) == null) {
                for (int mInt = 0; mInt < 5; mInt++) {
                    mItems.add(new Item(mInt, "Item " + mInt));
                }
            } else {
                mItems = new Gson().fromJson(SP.getString("items_order", null), new TypeToken<Item>(){}.getType());
            }

        }

        @Override
        public long getItemId(int position) {
            return mItems.get(position).id;
        }

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View mView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_view, parent, false);
            return new ViewHolder(mView);
        }

        @Override
        public void onBindViewHolder(final ViewHolder holder, final int position) {
            Item mItem = mItems.get(position);
            holder.mButton.setText(mItem.text);
        }

        @Override
        public int getItemCount() {
            return mItems.size();
        }

        @Override
        public void onMoveItem(int fromPosition, int toPosition) {
            Item mMovedItem = mItems.remove(fromPosition);
            mItems.add(toPosition, mMovedItem);
            notifyItemMoved(fromPosition, toPosition);
        }

        @Override
        public boolean onCheckCanStartDrag(ViewHolder holder, int position, int x, int y) {
            return true;
        }

        @Override
        public ItemDraggableRange onGetItemDraggableRange(ViewHolder holder, int position) {
            return null;
        }

        @Override
        public boolean onCheckCanDrop(int draggingPosition, int dropPosition) {
            return true;
        }

    }

    @Override
    protected void onPause() {
        super.onPause();
        mSaveItemsOrder = new ArrayList<>();
        for (int mInt = 0; mInt < mRecyclerView.getAdapter().getItemCount(); mInt++) {
            mSaveItemsOrder.add(mRecyclerView.getAdapter().getItemId(mInt));
        }

        mEditor.putString("items_order", new Gson().toJson(mSaveItemsOrder)).commit();
    }

This is the error: https://www.dropbox.com/s/j2tf4n08depyynt/Error.txt?dl=0

The problem is with your JSON. You the object you are serializing to JSON is mSaveItemsOrder which is an ArrayList . But on deserializing you give GSON the Class new TypeToken<Item>(){}.getType() . So you store an ArrayList in your JSON but trying to deserialzie a different Class, that won't work.
This should work:

mItems = new Gson().fromJson(SP.getString("items_order", null),  new TypeToken<ArrayList>(){}.getType(););

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM