屏幕方向更改后恢复Android GridView(无需重新加载)
我是Android新手(这是我的第一个应用程序),我在屏幕方向更改后恢复Android GridView(无需重新加载),android,gridview,screen-orientation,restore,android-configchanges,Android,Gridview,Screen Orientation,Restore,Android Configchanges,我是Android新手(这是我的第一个应用程序),我在活动中制作了一个GridView,我希望它能根据屏幕位置(纵向/横向)做出响应。当然,我为纵向和横向设置了一些自定义布局值GridViewrows width,效果非常好。 除此之外,在每次屏幕方向更改时,GridView将再次重新加载。这对用户体验不好。我只喜欢GridView(当然还有它的行)调整到新的屏幕宽度,而不需要执行所有onCreate()指令(从internet检索GridView的数据,在HashMap对象中分配退役数据,设置
活动中制作了一个GridView
,我希望它能根据屏幕位置(纵向/横向)做出响应。当然,我为纵向和横向设置了一些自定义布局值GridView
rows width,效果非常好。
除此之外,在每次屏幕方向更改时,GridView
将再次重新加载。这对用户体验不好。我只喜欢GridView
(当然还有它的行)调整到新的屏幕宽度,而不需要执行所有onCreate()
指令(从internet检索GridView
的数据,在HashMap
对象中分配退役数据,设置GridView
的Adapter
,然后显示GridView
的行)。
我浏览了许多论坛帖子和一些谷歌文档,其中谈到了如何恢复简单值,但在没有重新加载的情况下,从未找到恢复GridView
的答案。
我读过关于onSaveInstanceState()
和onRestoreInstanceState()
,但我不知道如何在我的案例中使用它们(GridView
案例)
有没有人能提供一个简单的代码示例?或者至少提供一些标题
以下是我在活动
课程中在代码中尝试的一些内容:
private Parcelable mListInstanceState;
private Parcelable mAdapterInstanceState;
private GridView gridView = null;
private MyAdapter myAdapter = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridView = (GridView) findViewById(R.id.gridview);
// Check whether we're recreating a previously destroyed instance
if(savedInstanceState != null) {
// Restore value of members from saved state
mListInstanceState = savedInstanceState.getParcelable("gridview");
mAdapterInstanceState = savedInstanceState.getParcelable("adapter");
}
else {
// Retrieve data from internet, fill HashMap object,
// set Adapter and display GridView only for the first time the activity is created
attemptToDisplayGirdViewItems();
}
}
@Override
protected void onSaveInstanceState(Bundle state) {
// Save activity state
super.onSaveInstanceState(state);
state.putParcelable("gridview", gridView.onSaveInstanceState());
// state.putParcelable("adapter", myAdapter);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
// Retrieve and restore activity state
// Restore state members from saved instance
mListInstanceState = savedInstanceState.getParcelable("gridview");
mAdapterInstanceState = savedInstanceState.getParcelable("adapter");
super.onRestoreInstanceState(savedInstanceState);
}
您不需要保存视图。如果视图具有ID,它们将自动保存(例如GridView的滚动位置)。您需要保存的是适配器的数据集
您的适配器可能包含一个项列表。除非这些项是基本项或String
或实现Serializable
,否则它们需要实现Parcelable
,才能工作
请参见此处的操作方法:
您的适配器需要一个getItems
方法,该方法返回数据集—您的包裹项目的ArrayList
。它还需要一个setItems(…)
方法或一个以项目列表为参数的构造函数
然后,您的活动将如下所示:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridView = (GridView) findViewById(R.id.gridview);
myAdapter = new MyAdapter(); // Create empty adapter.
if(savedInstanceState != null) {
ArrayList<MyItem> items = savedInstanceState.getParcelableArrayList("myAdapter");
myAdapter.setItems(items); // Load saved data if any.
}
gridView.setAdapter(myAdapter);
}
@Override
protected void onSaveInstanceState(Bundle state) {
super.onSaveInstanceState(state);
state.putParcelableArrayList("myAdapter", myAdapter.getItems());
}
@覆盖
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridView=(gridView)findViewById(R.id.gridView);
myAdapter=新建myAdapter();//创建空适配器。
如果(savedInstanceState!=null){
ArrayList items=savedInstanceState.getParcelableArrayList(“myAdapter”);
myAdapter.setItems(items);//加载保存的数据(如果有)。
}
setAdapter(myAdapter);
}
@凌驾
SaveInstanceState上受保护的无效(捆绑状态){
super.onSaveInstanceState(状态);
state.putParcelableArrayList(“myAdapter”,myAdapter.getItems());
}
您不需要保存视图。如果视图具有ID,它们将自动保存(例如GridView的滚动位置)。您需要保存的是适配器的数据集
您的适配器可能包含一个项列表。除非这些项是基本项或String
或实现Serializable
,否则它们需要实现Parcelable
,才能工作
请参见此处的操作方法:
您的适配器需要一个getItems
方法,该方法返回数据集—您的包裹项目的ArrayList
。它还需要一个setItems(…)
方法或一个以项目列表为参数的构造函数
然后,您的活动将如下所示:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridView = (GridView) findViewById(R.id.gridview);
myAdapter = new MyAdapter(); // Create empty adapter.
if(savedInstanceState != null) {
ArrayList<MyItem> items = savedInstanceState.getParcelableArrayList("myAdapter");
myAdapter.setItems(items); // Load saved data if any.
}
gridView.setAdapter(myAdapter);
}
@Override
protected void onSaveInstanceState(Bundle state) {
super.onSaveInstanceState(state);
state.putParcelableArrayList("myAdapter", myAdapter.getItems());
}
@覆盖
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridView=(gridView)findViewById(R.id.gridView);
myAdapter=新建myAdapter();//创建空适配器。
如果(savedInstanceState!=null){
ArrayList items=savedInstanceState.getParcelableArrayList(“myAdapter”);
myAdapter.setItems(items);//加载保存的数据(如果有)。
}
setAdapter(myAdapter);
}
@凌驾
SaveInstanceState上受保护的无效(捆绑状态){
super.onSaveInstanceState(状态);
state.putParcelableArrayList(“myAdapter”,myAdapter.getItems());
}
您应该只保存数据(来自internet)…使用不推荐的Activity.getLastNonfigurationInstance()保存数据
或使用UI较少的可保留片段…所有其他内容都应该在那里…GridView正在保存当前项在onSaveInstanceState中的位置
因此您应该对此感到烦恼…检查CacheFragment类及其用法…从internet获取的数据存储在JSONArray CacheFragment.response中
而且它在屏幕或显示更改中“存活”…loadData启动新请求或立即返回数据取决于响应是否已设置感谢@Selvin的帮助。我尝试了Eugen的解决方案,效果很好:)savedInstanceState解决方案有一个小问题-savedInstanceState限制(~1MB) ... 所以你应该注意这个解决方案。。。此外,包裹/解包裹将占用一些CPU周期。。。当只保留一个实例时,不会-因为您将得到完全相同的数据实例。。。所以,当我不是说这是一个糟糕的解决方案时,我不会用它myself@Selvin:谢谢!这是Google文档中关于大数据和幸存的配置更改所说的:…onSaveInstanceState()回调它不是为承载大对象(如位图)而设计的,其中的数据必须序列化然后反序列化,这会消耗大量内存并使配置更改变慢代码>。您应该只保存(来自internet的)数据。。。使用已弃用的Activity.getLastNonConfigurationInstance()
或使用UI较少的可保留片段的fx。。。所有其他的东西都应该在那里。。。GridView正在保存curre的位置