Android: восстановить позиции элемента RecyclerView после повторного открытия приложения

У меня есть список элементов CardView RecyclerView. Я сохраняю данные CardView в базе данных SQLite. Пользователь может перетащить CardViews вверх и вниз в списке, чтобы изменить порядок элементов. Когда пользователь выходит из приложения, я хотел бы сохранить текущий порядок элементов RecyclerView. Затем, когда пользователь снова откроет приложение, я бы хотел восстановить точный порядок элементов RecyclerView.

Я попытался несколько подходов, основанных на других сообщениях SO без удачи:

Сохранить положение прокрутки RecyclerView с помощью RecyclerView.State?

- RecyclerView хранить / восстанавливать состояние между действиями

Сохранить положение прокрутки RecyclerView в Android?

Каждый раз, когда я снова открываю приложение, я получаю заказ по умолчанию, основанный на исходной отметке времени CardView. Он показывает самый новый элемент CardView вверху списка, опускаясь до последнего элемента, который является самым старым CardView.

Вот мой код:

public class MainActivity extends AppCompatActivity {

    private ArrayList<ListItem> allList;
    private RecyclerView mRecyclerView;
    private SQLiteDB sqLiteDB;
    private MyRecylerAdapter adapter;
    private static final String KEY_RECYCLER_STATE = "recycler_state";
    private Parcelable recyclerViewState;

    protected void onCreate(Bundle savedInstanceState) {

        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        allList = new ArrayList<>();
        allList.clear();
        allList = sqLiteDB.getAllDBItems();
        adapter = new MyRecylerAdapter(this, allList);
        mRecyclerView.setAdapter(adapter);
    }

    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState); 

        outState.putParcelable(KEY_RECYCLER_STATE, mRecyclerView.getLayoutManager().onSaveInstanceState());     
    }

    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);

        recyclerViewState = savedInstanceState.getParcelable(KEY_RECYCLER_STATE);
    }    

    @Override
    protected void onResume() {
        super.onResume();        

        if (mRecyclerView !=null) {
            mRecyclerView.getLayoutManager().onRestoreInstanceState(recyclerViewState);
        }
    }
}    

public class SQLiteDB extends SQLiteOpenHelper {

    ...
    public ArrayList<ListItem> getAllDBItems() {
    ArrayList<ListItem> modelList = new ArrayList<>();

    SQLiteDatabase db = getReadableDatabase();        

    String[] columns = {
            ItemContract.ItemEntry.A,
            ItemContract.ItemEntry.B,
            ItemContract.ItemEntry.C,
            ItemContract.ItemEntry.D,
            ItemContract.ItemEntry.E,
            ItemContract.ItemEntry.F,
            ItemContract.ItemEntry.G,
            ItemContract.ItemEntry.H,
            ItemContract.ItemEntry.I,
            ItemContract.ItemEntry.J
    };

    Cursor getCursor = db.query(
            TABLE_NAME, 
            columns, 
            null,    
            null,   
            null,   
            null,   
            null    
    );

    try {
        if (getCursor.getCount() > 0) {
            getCursor.moveToFirst(); 

            while (!getCursor.isAfterLast()) {

                do { 
                    ListItem listItem = new ListItem();
                    listItem.setId(Integer.parseInt(getCursor.getString(getCursor.getColumnIndex(A))));
                    listItem.setType(getCursor.getString(getCursor.getColumnIndex(B)));
                    listItem.setTypeColor(Integer.parseInt(getCursor.getString(getCursor.getColumnIndex(C))));
                    listItem.setTodo(getCursor.getString(getCursor.getColumnIndex(D)));
                    listItem.setNote1(getCursor.getString(getCursor.getColumnIndex(E)));
                    listItem.setNote2(getCursor.getString(getCursor.getColumnIndex(F)));
                    listItem.setDuedate(getCursor.getString(getCursor.getColumnIndex(G)));
                    listItem.setDuetime(getCursor.getString(getCursor.getColumnIndex(H))); listItem.setTimestamp(Long.parseLong(getCursor.getString(getCursor.getColumnIndex(I))));
                    listItem.setRandint(Integer.parseInt(getCursor.getString(getCursor.getColumnIndex(J))));
                  modelList.add(0,listItem);
                } while (getCursor.moveToNext());
            }
        }
    } finally {
        if (getCursor != null && !getCursor.isClosed()) {
            getCursor.close();
        }
    } if(db.isOpen()) {
        db.close();
    }
    return modelList;
} 

public class ListItem {

    private int _id;
    private int _sortorder;

    public void setSortorder(int sortorder) {
    _sortorder = sortorder;

    } 
}

1 ответ

Решение

Добавьте поле с именем "SortOrder" в таблицу базы данных и увеличивайте значение в этом столбце при каждом добавлении новой строки. (Вы можете использовать функцию MAX, чтобы гарантировать, что значение всегда будет следующим от текущего максимального значения)

Сортировать по этому столбцу при получении элементов.

Когда вы перетаскиваете карточку после перетаскивания ее на новую позицию, обновите поле новым порядком / позицией сортировки.

Другие вопросы по тегам