rgamber
rgamber

Reputation: 5849

ArrayAdapter onResume() confusion

I have a class MyArrayAdapter which extends ArrayAdapter<MyClass>. Now I have a MyListFragment which extend ListFragment which uses the MyArrayAdapter. Class MyActivity adds the MyListFragment in the view.

So far so good.

Now, the user can change preferences, upon which I need to change some Strings in the List<MyClass>. Since the ArrayAdapter only recognizes onNotifyDataSetChanged() when its own methods like clear(), add(), etc are used on the List<MyClass> which I am not doing, I use the onResume to reload the data to reflect the changes.

So my MyListFragment contains the following:

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();
    }

}

This works but the problem with this is when the activity runs the first time, that there are now 2 trips to the database where one is required. So I modified the class as below:

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();
    }

}

So my question is, is the hack that I am doing by using boolean isSecondTime to make sure that the first time I don't make 2 trips to the DB reliable? The adapter saves the list of elements, so the second time onwards I make only one trip.

(Eg. If the user changes the preferences, switches to some other app, and Android decides to free some memory, and removes the MyListFragment from the memory, and when the user switches back, can I be assured that the List<Elements> will be fresh from the db? - This or any similar scenario)

Any suggestions are appreciated.

Upvotes: 0

Views: 392

Answers (2)

Dmide
Dmide

Reputation: 6462

I think you should store your Adapter in Activity, populate it only once at start and become independent of Fragment's lifecycle. Make a getter for it and access it from Fragment via (MyActivity) getActivity().getMyAdapter().

About your second question: if user switches to another app, there are 3 possible scenarios:

  1. User comes back quickly, nothing is changed.
  2. User comes back after a while, your app was cached and restored - still you'll get the same state of objects.
  3. User leaves your app for a long time, it's killed. App'll have to restart from scratch.

In all cases, you're safe.

Upvotes: 1

Tomas
Tomas

Reputation: 156

I always do this in 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);
    }
}

I add a new adapter every time I need to update the list.

Upvotes: 0

Related Questions