Osb*_*Cox 3 android listview android-listview android-fragments
我目前正在使用a custom list adapter并在运行时修改listview的行(更改文本,按钮等).
我想找到一种方法来保存/恢复listview在运行时创建的更改,当我启动另一个片段然后返回到包含listview的片段时.
目前,每次都会重新加载列表视图,并且所有运行时更改都将丢失.
以下显示了我如何设置列表适配器.
public void setAdapterToListView(ArrayList<item> list) {
ItemList = list;
ItemAdapter adapter = new MenuItemAdapter(list, getActivity(), this);
ItemListView.setAdapter(adapter);
}
Run Code Online (Sandbox Code Playgroud)
然后我使用自定义列表适配器在运行时进行更改(如上所述).以下是我在运行时如何更改内容的片段:
if (holder.qty.getText().toString().equals("Qty")) {
relativeLayout.setBackgroundColor(row.getResources().getColor(R.color.navDrawerL ightBlue));
holder.qty.setText("1");
holder.qty.startAnimation(anim);
holder.removeItem.setBackgroundResource(R.drawable.remove_item_red);
holder.removeItem.setEnabled(true);
...
Run Code Online (Sandbox Code Playgroud)
有没有推荐的方法来解决这个问题?
适配器
您将希望自定义适配器为其内部数据实现某种getter.例如
public ArrayList<YourDataType> getList() {
return new ArrayList<YourDataType>(mAdapterData);
}
Run Code Online (Sandbox Code Playgroud)
活动
然后在您的活动/片段中,您需要保存并恢复该数据.
private static final String STATE_LIST = "State Adapter Data"
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelableArrayList(STATE_LIST, getAdapter().getList());
}
Run Code Online (Sandbox Code Playgroud)
虽然有一种onRestoreInstanceState()方法可以覆盖,但我通常会在此期间恢复onCreate().通常在其他事物被实例化时更方便.要么可行,要么可行.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//If restoring from state, load the list from the bundle
if (savedInstanceState != null) {
ArrayList<YourDataType> list = savedInstanceState.getParcelableArrayList(STATE_LIST);
ItemAdapter adapter = new MenuItemAdapter(list, getActivity(), this);
} else {
//Else we are creating our Activity from scratch, pull list from where ever you initially get it from
ArrayList<YourDataType> list = getInitData();
ItemAdapter adapter = new MenuItemAdapter(list, getActivity(), this);
}
}
Run Code Online (Sandbox Code Playgroud)
YourDataType
你没有提到是什么YourDataType,但我认为它是一个自定义类.为了使用捆绑的savedstate,它必须实现Parcelable.Android的Parcelable 开发链接和StackOverFlow 帖子解释了如何使用Parcelable 编写自己的自定义类.
更新
根据您正在使用的片段,将决定是否onSavedInstanceState()将调用该方法.从问你的问题的方式来看,我假设你正在将一个片段推到backstack上以在另一个上面加载另一个片段.然后点击后退按钮将从后台重新加载该片段...并传递捆绑状态以从中重新加载.
当然,这只是众多场景中的一种.这个片段完全有可能只执行onPause()后跟onStop()...然后当重新显示片段时,只看到它onStart()后面跟着onResume().在这种情况下,没有保存状态,因为片段从未被完全销毁,因此没有任何东西可以恢复.它应该处于相同的状态.如果它不是,而是你看到它重新加载初始数据......那么你可能正在重新加载或之后的初始数据onStart().您需要将所有初始化数据移动到其他位置onCreate().
另一个可能的情况是你完全破坏片段而不将它放在后台上.重新初始化它不会有保存的状态.如果你想事先将这个片段"恢复"回状态,那么你就不能依赖它onSavedInstanceState().您需要手动将这些信息手动保存在内存,磁盘或数据库中.然后从中拉出来.
遗憾的是,带有片段的生命周期非常复杂,并且极大地依赖于使用,甚至在支持库与本机片段之间.
经过一些阅读/研究后,我最终通过使用 Gson ( https://code.google.com/p/google-gson/ ) 将适配器数据保存到“已保存的首选项”来解决这个问题。
我使用 Gson 首先将对象数组转换为 Json,然后将 Json 字符串存储在“已保存的首选项”中。
随后,我能够根据需要检索这些并再次将 Json 读入 Java 对象,将它们存储在数组列表中并将其传递给我的 listview 适配器。
以下是该过程的简要概述,供任何想要做类似事情的人参考。
保存到共享首选项:
SharedPreferences settings;
Editor editor;
settings = c.getSharedPreferences(PREFS_NAME,Context.MODE_PRIVATE);
editor = settings.edit();
Gson gson = new Gson();
String ItemsJson = gson.toJson(list);
editor.putString(categoryId, ItemsJson);
editor.apply();
Run Code Online (Sandbox Code Playgroud)
从共享偏好中读取:
if (settings.contains(categoryId) {
String jsonItems = settings.getString(categoryId, null);
Gson gson = new Gson();
Item[] favoriteItems = gson.fromJson(jsonItems, Item[].class);
list = Arrays.asList(favoriteItems);
ItemsFromSharedPrefs = new ArrayList<>(list);
AllCategories.addAll(ItemsFromSharedPrefs);
} etc...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8621 次 |
| 最近记录: |