在方向更改时恢复列表视图中的项目和滚动位置
Restore items and scroll position in listview on orientation change
我尝试通过多种方式在用户旋转 phone 时恢复列表视图的数据。但是,我遇到了一些困难,因为当我转动屏幕一次时,它就可以工作,但是当我再次将其翻转时,它不再起作用。另外,我尝试恢复滚动位置,但没有成功。
所以我想知道最好的方法。
我的代码:
private ListView item_container;
private ArrayList<Song.Hits> values;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
item_container = findViewById(R.id.bottom_popup_container);
}
当我完成从 API 中检索数据时,我将它们加载到列表视图中(并保存数据):
@Override
public void onRequestFinish(ArrayList<Song.Hits> hits) {
if (!hits.isEmpty()) {
CAdapter adapter = new CAdapter(hits);
item_container.setAdapter(adapter);
values = adapter.getHits();
};
}
最后,我覆盖了这2个方法来保存列表视图的位置和项目。
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
outState.putParcelableArrayList("list", values);
outState.putParcelable("pos", item_container.onSaveInstanceState());
super.onSaveInstanceState(outState);
}
@Override
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
ArrayList<Song.Hits> values = savedInstanceState.getParcelableArrayList("list");
if (values != null) {
CAdapter adapter = new CAdapter(values);
item_container.setAdapter(adapter);
item_container.onRestoreInstanceState(savedInstanceState.getParcelable("pos"));
}
}
您还应该更新 OnCreate 方法或覆盖 OnPostCreate 方法,并在检查 savedInstanceState!=null 时添加您在 onRestoreInstanceState 中使用的逻辑
您应该在 onCreate
上进行相同的检查,因为 onRestoreInstanceState
并不总是被调用,这有点棘手。
您可以从文档中查看:
This method is called after onStart()
when the activity is being
re-initialized from a previously saved state, given here in
savedInstanceState
. Most implementations will simply use
onCreate(Bundle)
to restore their state, but it is sometimes
convenient to do it here after all of the initialization has been done
or to allow subclasses to decide whether to use your default
implementation. The default implementation of this method performs a
restore of any view state that had previously been frozen by
onSaveInstanceState(Bundle)
.
将你的逻辑移到 onCreate
就可以了
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
item_container = findViewById(R.id.bottom_popup_container);
if (savedInstanceState != null) {
ArrayList<Song.Hits> values = savedInstanceState.getParcelableArrayList("list");
if (values != null) {
CAdapter adapter = new CAdapter(values);
item_container.setAdapter(adapter);
item_container.onRestoreInstanceState(savedInstanceState.getParcelable("pos"));
}
}
}
在不相关的程度上,您可能应该使用 RecyclerView
而不是 ListView
,它现在也支持自定义状态恢复策略,以便在设置数据之前自动保留滚动状态。
无论如何,按照目前的方法,应该像
一样简单
@Override
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
ArrayList<Song.Hits> values = savedInstanceState.getParcelableArrayList("list");
应该是
@Override
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
values = savedInstanceState.getParcelableArrayList("list");
我尝试通过多种方式在用户旋转 phone 时恢复列表视图的数据。但是,我遇到了一些困难,因为当我转动屏幕一次时,它就可以工作,但是当我再次将其翻转时,它不再起作用。另外,我尝试恢复滚动位置,但没有成功。
所以我想知道最好的方法。
我的代码:
private ListView item_container;
private ArrayList<Song.Hits> values;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
item_container = findViewById(R.id.bottom_popup_container);
}
当我完成从 API 中检索数据时,我将它们加载到列表视图中(并保存数据):
@Override
public void onRequestFinish(ArrayList<Song.Hits> hits) {
if (!hits.isEmpty()) {
CAdapter adapter = new CAdapter(hits);
item_container.setAdapter(adapter);
values = adapter.getHits();
};
}
最后,我覆盖了这2个方法来保存列表视图的位置和项目。
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
outState.putParcelableArrayList("list", values);
outState.putParcelable("pos", item_container.onSaveInstanceState());
super.onSaveInstanceState(outState);
}
@Override
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
ArrayList<Song.Hits> values = savedInstanceState.getParcelableArrayList("list");
if (values != null) {
CAdapter adapter = new CAdapter(values);
item_container.setAdapter(adapter);
item_container.onRestoreInstanceState(savedInstanceState.getParcelable("pos"));
}
}
您还应该更新 OnCreate 方法或覆盖 OnPostCreate 方法,并在检查 savedInstanceState!=null 时添加您在 onRestoreInstanceState 中使用的逻辑
您应该在 onCreate
上进行相同的检查,因为 onRestoreInstanceState
并不总是被调用,这有点棘手。
您可以从文档中查看:
This method is called after
onStart()
when the activity is being re-initialized from a previously saved state, given here insavedInstanceState
. Most implementations will simply useonCreate(Bundle)
to restore their state, but it is sometimes convenient to do it here after all of the initialization has been done or to allow subclasses to decide whether to use your default implementation. The default implementation of this method performs a restore of any view state that had previously been frozen byonSaveInstanceState(Bundle)
.
将你的逻辑移到 onCreate
就可以了
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
item_container = findViewById(R.id.bottom_popup_container);
if (savedInstanceState != null) {
ArrayList<Song.Hits> values = savedInstanceState.getParcelableArrayList("list");
if (values != null) {
CAdapter adapter = new CAdapter(values);
item_container.setAdapter(adapter);
item_container.onRestoreInstanceState(savedInstanceState.getParcelable("pos"));
}
}
}
在不相关的程度上,您可能应该使用 RecyclerView
而不是 ListView
,它现在也支持自定义状态恢复策略,以便在设置数据之前自动保留滚动状态。
无论如何,按照目前的方法,应该像
一样简单@Override protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); ArrayList<Song.Hits> values = savedInstanceState.getParcelableArrayList("list");
应该是
@Override
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
values = savedInstanceState.getParcelableArrayList("list");