bar*_*ian 41 android android-listview android-fragments
我正在使用Fragment和listView.我通过自定义Loader(来自互联网)收到的数据填充与此列表视图关联的ArrayAdapter.Custom ArrayAdapter支持无限滚动(分页).
当用户在ListView中旋转设备并保持滚动位置时,在ArrayAdapter中存储项目的最佳方法是什么?
我正在考虑使用ArrayAdapter创建非可视片段,并使用setRetainInstance方法来保存值.
有什么更好的解决方案吗?
Phi*_*hil 56
要使用Android框架和Fragment生命周期,您应该onSaveInstanceState在Fragment中实现该方法.为简单起见,我假设您有一个可以获得的String值数组(我通常扩展ArrayAdapter以封装视图构造并提供访问整个底层数据集的便捷方法):
public void onSaveInstanceState(Bundle savedState) {
super.onSaveInstanceState(savedState);
// Note: getValues() is a method in your ArrayAdapter subclass
String[] values = mAdapter.getValues();
savedState.putStringArray("myKey", values);
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以在onCreate方法(或onCreateView或onActivityCreated - 请参阅Fragment JavaDoc)中检索数据,如下所示:
public void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
String[] values = savedInstanceState.getStringArray("myKey");
if (values != null) {
mAdapter = new MyAdapter(values);
}
}
...
}
Run Code Online (Sandbox Code Playgroud)
这可确保正确处理所有生命周期事件,而不会丢失数据,包括设备轮换和用户切换到其他应用程序.不使用onSaveInstanceState和使用内存的危险是Android回收内存的危险.保存的状态不会受此影响,但使用实例变量或隐藏的片段会导致数据丢失.
如果savedStateInstance为null,则没有要恢复的状态.
这if (values != null)只是为了防止没有保存数组的可能性,但如果您编写ArrayAdapter来处理空数据集,则不需要这样做.
如果您的行是您自己的类之一而不是单个数据项的实例,那么最终的解决方案是在该类上实现Parcelable接口,然后您可以使用savedState.putParcelableArray("myKey", myArray).你会惊讶于知道如何实现Parcelable是多么有用 - 它允许你在内部传递你的类,并允许你编写更清晰的代码.
旋转设备后,应用程序将重新启动.因此onSaveInstance在应用程序被销毁之前调用.您可以保存数组适配器,onSaveInstance并在onCreate再次启动应用程序时最终调用该数组适配器,您可以检索数组适配器并将其设置为列表视图.
保存适配器的项目非常容易onSaveInstance.
现在您需要保存位置(滚动).你可以这样做
简单的方法
因为改变screenOrientation会使事情变得混乱,你可以允许一些边际错误,简单地说,在你的情况下onSaveInstance,使用保存第一个可见项目listView.getFirstVisiblePosition().
然后在您onRestoreInstance可以检索此索引以使用滚动到相同的项目listview.setSelection(position).当然,你可以使用,listview.smoothScrollToPosition(position)但那会很奇怪.
困难的方式
要获得更准确的位置,您需要再向下1级:获取滚动位置(而不是索引)并保存该位置.然后在恢复后,滚动回到此位置.在你的onSaveInstance,保存从中返回的位置listview.getScrollY().当您在自己中检索此位置时onRestoreInstance,可以使用滚动回到此位置listview.scrollTo(0, position).
为什么这真的很难?
简单.您很可能无法回滚到此位置,因为您的列表视图尚未通过测量和布局.您可以通过在使用设置适配器后等待布局来克服此问题getViewObserver().addOnGlobalLayoutListener.在此回调中,发布runnable以滚动到该位置.
我建议使用第一种"简单方法",因为一般来说,当屏幕方向改变时,用户可能会将手指向后移动.我们只需向他展示"给予或接受"的相同项目.
| 归档时间: |
|
| 查看次数: |
46144 次 |
| 最近记录: |