DEV Community

Cover image for List Fragments
Pete
Pete

Posted on • Edited on

List Fragments

ListFragment is a subclass of the Fragment class. List fragments are fragments that extend the ListFragment class. Fragments like this have special methods for working with lists and adapters, they do not need a layout file because they automatically have their own layout, and they have just one root view - a ListView. Modern list fragments can have a GridView though.

Creating a ListFragment

When you create a ListFragment subclass, you won't need to override onCreateView() unless you want to add some custom behavior to it.
If you want to override it however, you'll have to call super() in the method body.
Let's create a list fragment named DemoListFragment and override onCreateView()

public class DemoListFragment extends ListFragment {
    @Override
    public View onCreateview(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return super.onCreateView(inflate, container, savedInstanceState);
    }
}
Enter fullscreen mode Exit fullscreen mode

Code breakdown
In the onCreateView method, we did not inflate an xml layout file. This is because list fragments have their own layout automatically and so we don't need to inflate our own xml file.

Binding Data to ListFragments

In list fragments, you bind data to their ListViews with adapters just like in activities, but there are two major differences. They are:

  1. The constructor of an Adapter usually takes a Context argument. If you were constructing the Adapter in an activity, you would have passed it this as the Context argument because activities implement Context. But since the adapter is getting constructed in a fragment(an object that doesn't implement Context), you have to get the context from somewhere else. You have to pass it the result of calling getContext() on the LayoutInflater object.

Assuming you want to create an ArrayAdapter named adapter, for an array named demoArray and the layout for one list item is defined in the file list_item.xml, you can do the job with the code snippet below.

ArrayAdapter<String> adapter = new ArrayAdapter(inflater.getContext(), android.R.layout.list_item, demoArray);
setListAdapter(adapter);
Enter fullscreen mode Exit fullscreen mode
  1. We use setListAdapter() to set the adapter, and not .setAdapter(). That is because ListFragments already have a built-in reference to the list that you want to bind the adapter to. So you don't need to call it explicitly.

Responding to Clicks in the List Fragment

ListFragment implements a listener automatically so you just have to implement the method onListItemClick() to respond to clicks.
You can implement onListItemClick() the default way - just by adding custom code to it - but it will make your Fragment tightly coupled to your activity. To achieve loose coupling, you'll have to go extra steps. These steps are:

  1. Create an interface named Listener that has a handler method named itemClicked(). Any activity that we want to respond to clicks will implement the interface and override its method.
static interface Listener {
    void itemClicked(long id);
}
Enter fullscreen mode Exit fullscreen mode
  1. Create a private field inside the ListFragment to keep a reference to the activity that is listening.
private Listener listener;
Enter fullscreen mode Exit fullscreen mode
  1. Register the activity that the fragment is being attached to as an implementer of that interface.
@Override void onAttach(Context context) {
    super.onAttach(context);
    this.listener = (Listener) context;
}
Enter fullscreen mode Exit fullscreen mode
  1. In the list fragment's onListItemClick() method, respond to clicks by calling the listener's handler method named itemClicked().
public void onListItemClick(ListView listView, View itemView, int position, long id) {
    if (listener != null) {
        listener.itemClicked(id);
    }
}
Enter fullscreen mode Exit fullscreen mode

With these done, we can implement the Listener interface in any Activity our ListFragment will be attached to, override its itemClicked() method and write some custom logic in it to handle the click.

class DemoActivity extends AppCompatAtivity implements Listener {
    @Override 
    void itemClicked(long id) {
        // You can add custom logic here
    }
}
Enter fullscreen mode Exit fullscreen mode

Previous article: Getting an Activity and a Fragment to Interact

Coming up next: Switching Fragments Programatically

Top comments (0)