我目前正在使用custom list adapter
并在运行时修改listview的行(更改文本,按钮等)。
当我启动另一个片段然后返回包含listview的片段时,我想找到一种方法来保存/恢复在运行时对listview
所做的更改。
目前每次都会重新加载列表视图,并且所有运行时更改都将丢失。
以下显示了我如何设置列表适配器。
public void setAdapterToListView(ArrayList<item> list) {
ItemList = list;
ItemAdapter adapter = new MenuItemAdapter(list, getActivity(), this);
ItemListView.setAdapter(adapter);
}
然后我使用自定义列表适配器在运行时进行更改(如上所述)。这是我在运行时如何改变事物的片段:
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);
...
是否有建议的方法来解决此问题?
答案 0 :(得分:5)
<强>适配器强>
您需要自定义适配器为其内部数据实现某种getter。例如
public ArrayList<YourDataType> getList() {
return new ArrayList<YourDataType>(mAdapterData);
}
<强>活动强>
然后在您的活动/片段中,您需要保存并恢复该数据。
private static final String STATE_LIST = "State Adapter Data"
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelableArrayList(STATE_LIST, getAdapter().getList());
}
虽然您可以覆盖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);
}
}
<强> YourDataType 强>
你没有提到YourDataType
是什么,但我认为它是一个自定义类。为了使用捆绑的保存状态,它必须实现Parcelable
。 Android的par link和StackOverFlow post解释了如何用Parcelable编写自己的自定义类。
<强>更新强>
根据您对片段的处理方式,将决定是否调用onSavedInstanceState()
方法。从问你的问题的方式来看,我假设你正在将一个片段推到backstack上以在另一个上面加载另一个片段。然后按下后退按钮将从后台重新加载该片段...并传递捆绑状态以从中重新加载。
当然,这只是众多场景中的一种。相关片段完全有可能只执行onPause()
后跟onStop()
...然后在重新显示片段时,只看到onStart()
后跟onResume()
。在这种情况下,没有保存状态,因为片段从未被完全销毁,因此没有任何东西可以恢复。它应该处于相同的状态。如果不是,而是你看到它重新加载初始数据......那么你可能正在onStart()
之内或之后重新加载初始数据。您需要将所有初始化数据移至onCreate()
。
另一种可能的情况是你完全破坏片段而不将它放在后台上。重新初始化它不会有保存的状态。如果您想要将此片段“恢复”回状态,那么您就不能依赖onSavedInstanceState()
。您需要手动将这些信息手动保存在内存,磁盘或数据库中。然后从中拉出来。
遗憾的是,带有片段的生命周期非常复杂,并且在很大程度上取决于使用情况,甚至在支持库与原生片段之间也是如此。
答案 1 :(得分:0)
在做了一些阅读/研究之后,我最终通过使用Gson(https://code.google.com/p/google-gson/)将适配器数据保存到Saved Preferences来解决这个问题。
我使用Gson首先将我的对象数组转换为Json,然后将Json字符串存储在Saved Preferences中。
随后我可以根据需要检索这些并再次将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();
从共享首选项中读取
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...