简体   繁体   English

如何使用Json保存和恢复RecyclerView Items的位置

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

I have a RecyclerView with 5 items and drag & drop feature. 我有一个RecyclerView,其中包含5个项目和拖放功能。 I want to save items's positions into SharedPreferences in order to restore them when the App is launched. 我想将项目的位置保存到SharedPreferences中,以便在启动应用程序时将其还原。 Currently I'm able to save their positions into SharedPreferences using Json but the App crashes when I restore positions. 目前,我可以使用Json将其职位保存到SharedPreferences中,但是当我恢复职位时,应用程序崩溃。 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 这是错误: https : //www.dropbox.com/s/j2tf4n08depyynt/Error.txt?dl=0

The problem is with your JSON. 问题出在您的JSON上。 You the object you are serializing to JSON is mSaveItemsOrder which is an ArrayList . 您要序列化为JSON的对象是mSaveItemsOrder ,它是一个ArrayList But on deserializing you give GSON the Class new TypeToken<Item>(){}.getType() . 但是在反序列化时,您给GSON类提供了new TypeToken<Item>(){}.getType() So you store an ArrayList in your JSON but trying to deserialzie a different Class, that won't work. 因此,您将ArrayList存储在JSON中,但尝试反序列化另一个类,这将无法工作。
This should work: 这应该工作:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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