I am an aspiring android developer who is learning as he goes. I realized that writing short articles on the things that I am learning would help my learning process, but also benefit those who are looking for the same help. StackOverflow has been one of the most useful sites for learning things piecemeal, but the clarity of answers from busy coders can vary and be difficult to understand based on your current ability level.
Problem
I want to display a scrolling list (using ListView) on a ViewPager Fragment. However, it doesn’t seem to work the same way that it would when simply displaying a list on a normal Android Activity.
As you probably know, the Java code that accompanies each Android Activity needs to have a a snippet of code that references corresponding XML objects that exist inside of the activity. Normally, this might look like:
Toolbar toolbar = findViewById(R.id.toolbar);
The first part Toolbar toolbar
is what the object will be designated as in the java code. It is being assigned the “view” , which is a toolbar in the case. The second part is concerned with the activity. The findViewById
tells Android Studio to search for something in an Android Activity. Last, R.id.toolbar
is the equivalent of a filepath, which shows Android Studio exactly where to find the object you are referencing. This is a very useful bit of code that allows you to tie java code to elements in your android activity.
Referencing inside of a ListFragment
The whole view referencing thing was really confusing to me coming into android. My code was throwing errors when trying to find the reference for my list, which I created in the Android activity:
ListView listView = findViewById(android.R.id.list);
From what I was able to learn, I needed to instead reference the rootView to still properly reference the list above:
ListView listView = rootView.findViewById(android.R.id.list);
The way I understand it, your Activity has its own layout which could be something like LinearLayout, ConstraintLayout etc. Your FragmentActivity lives inside of another Activity and has its own layout. Since your fragment activity is nested inside of another activity, the attached rootView shown above is necessary for the reference work. On the other hand, when you just have findViewById it is actually referencing this.findViewById
, which will reference the main Activity, instead of the fragment.
Setting up the ListAdapter
The next challenge faced is setting up the ListAdapter. Similar to the reference adjustments that we had to make for the fragment, you need to make the same adjustments when setting up a ListAdapter. In my example, I used an ArrayList to store the information I wanted to display. I took the ArrayList and passed the information into a ArrayAdapter, which I then assigned to a ListAdapter.
If this code was not displayed in a fragment, I would display it like this:
ListAdapter exAdapter2 = new ArrayAdapter<String>
(this
android.R.layout.simple_list_item_1, dailyEx);
listView.setAdapter(exAdapter2);
Inside of a fragment, it needs to be displayed like this:
ListAdapter exAdapter2 = new ArrayAdapter<String>
(getActivity(),
android.R.layout.simple_list_item_1, dailyEx);
listView.setAdapter(exAdapter2);
From my understanding, getActivity must be called since Fragments do not inherit from the Context class, which contains a helpful method called getSystemService for obtaining the context needed for the ArrayAdapter. Note that dailyEx is the name of my ArrayList, noted earlier in my code as: static ArrayList<String> dailyEx = new ArrayList<>();
One final thing to note is that all of the code for setting up the list adapter should fall under public static class PlaceholderFragment extends ListFragment {
As a newbie mistake, I had tried to put the code in the overall Java class associated with the root activity and not the fragment activity which was embedded with in root activity's java class. Since I used the template from Android studio, PlaceholderFragment was set up by default to extend Fragment and not ListFragment. Since I was using a ListView, I also made that change.
Now, I have a ViewPager with a list on each page. I am working on building an exercise app, and users will need a list on each page to track exercises. Hope you found this article useful. Please leave any comments for how this method can be improved!
