使用自定义列表适配器保存和恢复ListView

时间:2015-03-23 00:24:49

标签: android listview android-fragments android-listview

我目前正在使用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);

   ...

是否有建议的方法来解决此问题?

2 个答案:

答案 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...