Android:应用重新打开后恢复 RecyclerView 项目位置
Android: restore RecyclerView item positions after app re-opens
我有一个 CardView 项目的 RecyclerView 列表。我将 CardView 数据保存到 SQLite 数据库中。用户可以在列表中上下拖动 CardView 来更改项目的顺序。当用户退出应用程序时,我想保存 RecyclerView 项目的当前顺序。然后当用户重新打开应用程序时,我想恢复 RecyclerView 项目的确切顺序。
我尝试了多种基于其他 SO 帖子的方法,但没有成功:
--
--
--
我每次重新打开应用程序时得到的是我基于 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;
}
}
将名为 "SortOrder" 的字段添加到您的数据库 table 并在每次添加新行时递增此列中的值。 (您可以使用 MAX 函数来确保该值始终是当前最高值的下一个值)
检索项目时按此列排序。
当您将卡片拖到新位置后放下时,使用新排序更新字段 order/position。
我有一个 CardView 项目的 RecyclerView 列表。我将 CardView 数据保存到 SQLite 数据库中。用户可以在列表中上下拖动 CardView 来更改项目的顺序。当用户退出应用程序时,我想保存 RecyclerView 项目的当前顺序。然后当用户重新打开应用程序时,我想恢复 RecyclerView 项目的确切顺序。
我尝试了多种基于其他 SO 帖子的方法,但没有成功:
--
--
--
我每次重新打开应用程序时得到的是我基于 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;
}
}
将名为 "SortOrder" 的字段添加到您的数据库 table 并在每次添加新行时递增此列中的值。 (您可以使用 MAX 函数来确保该值始终是当前最高值的下一个值)
检索项目时按此列排序。
当您将卡片拖到新位置后放下时,使用新排序更新字段 order/position。