First, let me say that I really like this book. The book is very well-written and I sat down and read straight through chapters 1 - 7 and wrote all the code.
Of course, chapter 8 covers a lot of topics all at once and I understand that, because you have to get it all working to get it working at all. That’s fine.
My Experience With Chapter 8
I read the chapter and then spent long hours converting the first version of the app into the one which shows the initial list of items. I finally got it but I still wanted more understanding of how all those classes worked together. I analyzed it closely and I believe the following overview and details will really help other readers see what is actually happening.
The Class Diagram
I am going to add a diagram, however, the diagram itself only provides an overview. The diagram can add to understanding, but it cannot explain everything. For that, I will also provide the details of what happens when the app starts. Together I believe you’ll see that you can better understand what is going on.
The other thing that the diagram makes evident is that there is a lot going on. There are a lot of classes involved and even some somewhat circular references in there which is why the code feels so terribly difficult.
First, just take a look at the class diagram, as an overview. Don’t try to understand everything about what is going on, instead just recognize that there are a fairly large number of classes.
After you examine it I’ll point out a few things in an attempt to clarify.
Reading the Diagram
First of all, notice that the arrow heads that are open indicate where one class uses another class. The one closed-head arrow does actually indicate inheritance. You can see that my CrimeListActivity is a SimpleFragmentActivity.
Also notice that the class listed in upper right corner of each box is the type of each class (if there is a superclass). For instance, the CrimeAdapter class is a RecyclerView.Adapter. Also, notice that the +(plus sign) indicates public methods. - (minus sign) indicates private methods/properties and the # (hash) indicates protected methods.
However, the rest of the arrows are just indicating where one class uses another class. For example, the CrimeAdapter uses two classes (Crime and CrimeHolder). The CrimeListFragment uses the CrimeAdapter and of course the CrimeAdapter uses the Crime class. These levels of indirection (a class uses a class that uses a class) can be quite confusing.
Instantly, one thing the diagram does is provide you with an overview of all the things (classes) involved and all the actions (functions) that occur.
What The Diagram Helps Clear Up
I also believe the diagram begins to clear up the convoluted code that we see in the actual sample.
Keep in mind, I am not saying the authors made the code too complex. Instead, it is the Android API that has really done that. What I mean is that to use the RecyclerView you automatically step into a higher level of complexity because of what is required. But, even after you get the code working you may not understand exactly what is going on. I think the diagram helps in this way to see how the classes interact (use each other).
Confusing Redundancy Is A Bit More Clear
I also believe that a point of confusing redundancy is made more obvious by the diagram. You can easily see that there are three different classes which use the Crime class (CrimeLab, CrimeAdapter and CrimeHolder). It feels odd in the code and it’s difficult to get your head wrapped around it. However, here we can see that each of those classes needs to use the Crime class for its own purpose.
What About Class Behaviors?
The class diagram gives us a good structural look but says little about behaviors so now I’ll list how the classes are used when the app starts.
My main Activity class is CrimeListActivity. It is registered as the Launcher in the AndroidManifest so that is where everything starts. Of course, it is derived from the SimpleFragmentActivity so when the app launches it starts CrimeListActivity which calls the base class (SimpleFragmentActivity) onCreate() method.
The SimpleFragmentActivity.onCreate() calls createFragment() which we have overriden in our derived class (CrimeListActivity).
Inside createFragment() the method simply creates a new CrimeListFragment().
When it does that, the CrimeListFragment.onCreateView() fires which does the work to create the RecyclerView.
After it creates the RecyclerView, the CrimeListFragment calls the UpdateUI() method.
UpdateUI() makes sure a CrimeLab (list of crimes is created). This is the list which will eventually be displayed in the RecyclerView.
To display the list of crimes we have to use an Adapter class, so at this point the UpdateUI() method creates a new CrimeAdapter which takes a list of crimes. A CrimeAdapter is actually a special RecyclerView.Adapter. But notice that is is actually defined in the following way:
CrimeAdapter extends RecyclerView.Adapter<CrimeHolder>
Using natural language we would say that CrimeAdapter is a RecyclerView.Adapter of CrimeHolder.
Or, we might say, “A container of CrimeHolders”.
A lot happens when UpdateUI() news up one of these with the following code:
mAdapter = new CrimeAdapter(crimes);
That actually causes the onCreateViewHolder() method to fire after the CrimeAdapter constructor.
When onCreateViewHolder runs it :
- creates a new inflater object that can is used in the call to the CrimeHolder constructor
- news up a CrimeHolder() and returns it
When CrimeHolder() gets constructed it :
- inflates your list_item_crime.xml(two textviews - title and created date)
- sets the title and created textview to the value of the displayed crime
The CrimeHolder constructor is called 10 - 13 times depending upon how many Crimes will fit on your screen.
Then, each time you scroll a new item onto the screen the CrimeHolder constructor will fire again to inflate the list_item_view and display the data for the new crime.
That’s about as far as I have gotten at this point. I hope this helps to add some clarity to Chapter 8, although it also should help to show that chapter 8 covers a lot of territory. This part of the Android API works a lot of magic and there’s a lot going on underneath everything. I will study this more in an attempt to be able to implement these views on my own, because I do see how fast they are.