Question

I developed an app which fills a list. It works fine in the way I did it but I'm not conviced that I solved the problem in a recommended way. I read that you should override onActivityCreated in a Fragment and fill the list there instead of doing this in onCreateView. onCreateView should only be used to inflate static views. Is this true? If yes, how should these two methods look like in the end?

This is my Fragment class:

public class FragmentMain extends Fragment {

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.fragment_main, container, false);

    List<MyItem> items = createListItems();
    ListView listView = (ListView) view.findViewById(R.id.list);
    MyListAdapter adapter = new MyListAdapter(view.getContext(), items);
    listView.setAdapter(adapter);
    listView.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {
            Toast.makeText(view.getContext(),
                    "Clicked " + position, Toast.LENGTH_LONG)
                    .show();

        }
    });

    return view;
  }
.
.
.
}

My MainActivity just adds the fragment:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        FragmentMain fm = new FragmentMain();
        getFragmentManager().beginTransaction()
                .add(R.id.fragment_main_container, fm).commit();

    }
.
.
.
}
Was it helpful?

Solution

That is true to a certain extend only because onCreateView happens on the UI thread and you don't want anything slowing that down otherwise your UI will be slow and choppy. For example, in your fragment class you have a call to a method "createListItems()". I don't know how many items you're making but if it's a lot it could slow down your UI (especially if youre accessing a database and querying objects and so on). So you could do it in onActivityCreated but you could also use an AsyncTask. So your code would become something like this:

public class LoadListObjectsTask extend AsyncTask<Void, List<MyItem>, Void> {

  private MyListAdapter myListAdapter;
  private Context mContext;

  public LoadListObjectsTask(Context context) {
     this.mContext = context;
  } 


  @Override 
   public void doInBackground(Void...params) {
     //create your list objects here instead of on UI thread. This will run on a separate thread.
   myListAdapter = new MyListAdapter(mContext, items);
   return items; //return list of MyItems
   }


   //This is called when doInBackground is done. THIS WILL RUN ON THE UI THREAD So don't do 
   //anything slow here
   @Override 
   public void onPostExecute(List<MyItem>...params //don't really need the list here//) {
     listView.setAdapter(myListAdapter);
   }
}

then in your fragment

public class FragmentMain extends Fragment {

private ListView listView;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.fragment_main, container, false);

    List<MyItem> items = new ArrayList<MyItem>();
    listView = (ListView) view.findViewById(R.id.list);

   //new code
    new LoadListObjectsTask(getActivity()).execute();

    listView.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {
            Toast.makeText(view.getContext(),
                    "Clicked " + position, Toast.LENGTH_LONG)
                    .show();

        }
    });

    return view;
  }

 public void onResume()... {
  //also add the task here so your content is reloaded on resume..
  new LoadListObjectsTask(getActivity()).execute();
 }
.
.
.
}

If you don't want to do this just make your List of MyItems a private field and move

List<MyItem> items = createListItems();

to onActivityCreated().

Hope that helps!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top