【问题标题】:ArrayAdapter onResume() confusionArrayAdapter onResume() 混淆
【发布时间】:2014-02-24 15:39:32
【问题描述】:

我有一个类MyArrayAdapter,它扩展了ArrayAdapter<MyClass>。 现在我有一个MyListFragment,它扩展了ListFragment,它使用了MyArrayAdapterMyActivity 类在视图中添加 MyListFragment

到目前为止一切顺利。

现在,用户可以更改首选项,在此基础上我需要更改List<MyClass> 中的一些字符串。由于 ArrayAdapter 仅在 clear(), add(), etc 等自己的方法用于 List<MyClass> 时才识别 onNotifyDataSetChanged(),而我没有这样做,因此我使用 onResume 重新加载数据以反映更改。

所以我的MyListFragment 包含以下内容:

public class MyListFragment extends ListFragment {

    private List<MyClass> elements = null;
    private MyListAdapter myListAdapter = null;

    public MyListFragment(List<MyClass> elements) {
        this.elements = elements;
    }

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        myListAdapter = new MyListAdapter(inflater.getContext(), R.layout.foo, elements);
        setListAdapter(myListAdapter);
        return super.onCreateView(inflater, container, savedInstanceState);
    }

    @Override
    public void onResume() {
        myListAdapter.clear();
        myListAdapter.addAll( sqliteclass.getAllElements() );
        myListAdapter.notifyDataSetChanged();
        isSecondTime = true;
        super.onResume();
    }

}

这可行,但问题是当活动第一次运行时,现在有 2 次行程 到需要一次的数​​据库。所以我修改了类如下:

public class MyListFragment extends ListFragment {

    private List<MyClass> elements = null;
    private MyListAdapter myListAdapter = null;
    private boolean isSecondTime = false;        //NEW

    public MyListFragment(List<MyClass> elements) {
        this.elements = elements;
    }

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        myListAdapter = new MyListAdapter(inflater.getContext(), R.layout.foo, elements);
        setListAdapter(myListAdapter);
        return super.onCreateView(inflater, container, savedInstanceState);
    }

    @Override
    public void onResume() {
        if(isSecondTime){       //NEW
            myListAdapter.clear();
            myListAdapter.addAll( sqliteclass.getAllElements() );
        }                       //NEW
        myListAdapter.notifyDataSetChanged();
        isSecondTime = true;
        super.onResume();
    }

}

所以我的问题是,我通过使用 boolean isSecondTime 来确保我第一次不进行 2 次访问数据库的操作是否可靠?适配器保存了元素列表,所以第二次以后我只做了一次。

(例如,如果用户更改了首选项,切换到其他应用程序,Android 决定释放一些内存,并从内存中删除 MyListFragment,当用户切换回来时,我可以确保List&lt;Elements&gt; 会从数据库中恢复过来吗?- 这个或任何类似的场景)

欢迎提出任何建议。

【问题讨论】:

  • 如果您的数据来自(至少 sqliteclass 的名称如此暗示)sqlite,您为什么要使用 ArrayAdapter?使用 SimpleCursorAdapter
  • 听起来不错。我会看看SimpleCursorAdapter 是否更适合我的需要并回来..
  • 考虑研究 SimpleCursorAdapter

标签: android android-fragments android-arrayadapter


【解决方案1】:

我认为您应该将Adapter 存储在Activity 中,在开始时仅填充一次并独立于Fragment's 生命周期。为它创建一个 getter 并从Fragment 通过(MyActivity) getActivity().getMyAdapter() 访问它。

关于你的第二个问题:如果用户切换到另一个应用程序,有3种可能的情况:

  1. 用户很快回来,没有任何改变。
  2. 用户一段时间后回来,您的应用已缓存并恢复 - 你仍然会得到相同的对象状态。
  3. 用户离开你的应用很长时间,它被杀死了。应用程序必须 从头开始。

在所有情况下,您都是安全的。

【讨论】:

    【解决方案2】:

    我总是在 onResume() 中这样做

    public void setList() {
        Log.i("setList","");
        ArrayAdapter<String> adapter=new ArrayAdapter<String>(this, android.R.layout.simple_list_item_multiple_choice);
        if (items.size()<1)
            adapter.add(getString(R.string.emptylist));
        for(int i=0;i<items.size();i++) {
            adapter.add(items.get(i).item);
        }
        todolist.setAdapter(adapter);
        for(int i=0;i<items.size();i++) {
            todolist.setItemChecked(i, items.get(i).checked);
        }
    }
    

    每次需要更新列表时,我都会添加一个新适配器。

    【讨论】:

    • 是的,这是一个选项,但是每次添加一个新的适配器需要大量的资源,也使用大量的垃圾收集。所以我想避免这种情况。
    猜你喜欢
    • 1970-01-01
    • 2011-02-26
    • 2013-04-19
    • 1970-01-01
    • 2014-07-09
    • 1970-01-01
    • 2014-05-06
    • 2015-02-02
    • 2011-05-11
    相关资源
    最近更新 更多