Jacob Joz
Jacob Joz

Reputation: 732

getActivity returns null in Fragment

I have a fragment which is basically a list view. The parent activity calls a method to retrieve a list of roster items from a service. When the data returns from the service I call updateRosterItems on the fragment passing through and ArrayList of Roster items. The problem is that it works the first time through, but then when I select a different tab, and then come back to the tab with the fragment, the getActivity() returns null and I can't hook up the data to the ArrayAdapter.

This is the code for the updateRosterItems function:

public void updateRosterList(ArrayList<RosterInfo> rosterItems)
{
    if(_adapter == null)
    {
        _adapter = new RosterItemAdapter(getActivity(), R.layout.roster_listview_item, rosterItems);
    }

    Activity activity = getActivity();
    if(activity != null)
    {
        ListView list = (ListView)activity.findViewById(R.id.lstRosterItems);

        list.setAdapter(_adapter);
        _adapter.notifyDataSetChanged();
    }
}

I've read about similar issues caused by code being called before the fragment is attached. I guess my question is, is there a way to delay the call to the updateRosterList until after the onAttach is called? The solution I'm toying with is that if getActivity() returns null then store the data in private variable in the fragment, and in the onAttach method check if there is data in the varialbe and then call the update on the adapter. This seems a bit hacky though. Any ideas?

Upvotes: 1

Views: 5318

Answers (2)

Jacob Joz
Jacob Joz

Reputation: 732

UPDATE: I've managed to get it working by doing this. I'm quite new to Android development and it seems a bit hacky to me as a solution. Is there a better way? Basically the updateRosterList function is the one that is called from outside of the fragment.

public class RosterListFragment extends Fragment {

RosterItemAdapter _adapter = null;
private ArrayList<RosterInfo> _items;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    return inflater.inflate(R.layout.roster_listview, container, false);
}

@Override
public void onActivityCreated(Bundle savedInstanceState)
{
    super.onActivityCreated(savedInstanceState);

    if(_items != null)
    {
        performUpdateRosterList(_items);
    }

}

public void updateRosterList(ArrayList<RosterInfo> rosterItems)
{
    Activity activity = getActivity();
    if(activity != null)
    {
        performUpdateRosterList(rosterItems);
    }
    else
    {
        _items = rosterItems;
    }
}

private void performUpdateRosterList(ArrayList<RosterInfo> rosterItems)
{
    Activity activity = getActivity();
    if(_adapter == null)
    {
        _adapter = new RosterItemAdapter(activity, R.layout.roster_listview_item, rosterItems);
    }

    ListView list = (ListView)activity.findViewById(R.id.lstRosterItems);

    list.setAdapter(_adapter);
    _adapter.notifyDataSetChanged();
}

}

Upvotes: 2

PearsonArtPhoto
PearsonArtPhoto

Reputation: 39698

You are correct, the activity isn't yet attached. There's two ways to handle this.

  1. Don't make the changes until after the activity has been attached. Perhaps just save off rosterItems, and have it updated later.
  2. Pass in the context into your updater function.

Personally, I would say the first is probably be better path, but either one could work fine.

Upvotes: 1

Related Questions