Welcome to this review of the Pluralsight course Improving User Interface Design with Android Fragments by Jim Wilson
Jim has over 30 years of software engineering experience, with the past 15 years heavily focused on creating mobile device and location-based solutions. He has co-founded multiple software-related startups and has served in a consulting role at several more.
After nearly a decade as a Microsoft Device Application Development MVP, Jim now focuses on developing Android and iOS device applications. Jim’s passion is mentoring software developers. He blogs at hedgehogjim.wordpress.com.
Improving User Interface Design with Android Fragments is the 8th course in the Pluralsight learning path for Android, and this month I am reviewing every course in this learning path.
Fragments and UI Modularization
Android devices differ widely. We have tiny screens for some mobile phones and giant displays for some tablets. We also have different orientations: tall and thin, wider and shorter etc.
We cannot just build one simple layout and hope that it works well across all devices.
Fragments are the foundation of UI modularization, allowing us to break the screen up into sections, and work with them as subsections.
They allow us to make our UI much more adaptable and it is used very widely across Android nowadays.
It’s used for tabbed displays, dialog boxes, action bar customization and much more.
At the time of the course recording at the end of 2012, Fragments were supported by 99.8% of active Android devices. At the time of writing this (October 2016), you can round up this to 100% and be close enough.
In short, there is no reason not to use Fragments.
There are just a few simple steps involved with creating a fragment:
- Declare a class which inherits from Fragment
- Provide the fragment’s display contents
- Attach your fragment to an Activity
Jim explains each of these points here.
Fragment simplify supporting differing devices by allows us to adapt intelligently to different device capabilities.
Demo: Creating Fragments
We have an example program with a few different activities.
We start by looking at a split view activity. This has a list of Jim’s Android courses at the top, and the description of the selected course at the bottom.
How is this done? We see in SplitActivity.java there is very little code involved. It just loads a layout, and when we go to the split_activity.xml layout file, this is also simple.
It’s a LinearLayout with two fragments inside it: a course name fragment and a course description fragment.
course_names_fragment.xml contains more lines of XML, but it is still quite simple. It has a RadioGroup with several RadioButton controls.
CourseDescriptionFragment.xml is super simple and is just a LinearLayout with one TextView in it.
Jim says one of the first things we get from Fragments is automatic code generation.
We see in the emulator that things don’t look right in landscape mode. The description is laid on top of some of the course names. Jim says we can achieve the look we desire with no code.
We see this achieved with XML changes. We switch our LinearLayout from a vertical to a horizontal orientation, change the layout_width values to 0, and the layout_height values to “match_parent”.
We see in the emulator that it switches automatically from a vertical to a horizontal layout when we switch from portrait to landscape orientation. This is a massive improvement over the earlier design.
Jim says this alone would be worth a lot, but Fragments offer this and much more.
Coordinating Fragment Content
An activity is usually made up of several Fragments, and these need to be synchronized in some way.
Jim says content in one fragment is often affected by something a user does in another fragment. How do we coordinate this without tightly coupling them?
Jim has found the best approach is to use an application-defined interface.
Google have developed the FragmentManager, and this is responsible for all aspects of fragments inside of an activity.
Each activity has it’s own FragmentManager which is responsible for showing, hiding and locating all of the fragments in the activity.
Jim says when the UI changes, the FragmentManager often tears down the old fragment and creates a new one, and that’s what we saw in the previous lesson when we changed from portrait to landscape orientation.
We see an illustration of a bucket, representing the area where we store the state of the fragment.
There’s a callback called onSaveInstanceState that allows us to store the state into this bucket.
When a new instance is created, this object bucket is passed in to the onCreate methods. This let’s us recreate our earlier state within our fragment.
Demo: Coordinating Fragment Content
In our app, the course description doesn’t change when we select a new course item, so that’s what we want to fix.
We don’t want one fragment talking directly to another. To manager the coordination, Jim creates a CourseFragmentCoordinator interface and implements it in SplitActivity.
The interface has only one method and this is named onSelectedCourseChanged. In here we get our FragmentManager and the CourseDescriptionFragment reference within it, so that we can call setDisplayedDescription on it.
In CourseNamesFragment.java there’s a click handler. In here we get our activity and cast it to our CourseFragmentCoordinator interface. We then call onSelectedCourseChanged on it.
In the emulator we see the course description now changes with or course selection.
But when we switch to landscape mode, the description falls back to our default course.
We see how to fix this by implementing the onSaveInstanceState callback.
Supporting Fragments Across Activities
As our user interfaces get ricer, our application may need to take much more direct control over the layout management.
Jim says the FragmentManager is a key part of managing any fragment issues we may run into, because it’s useful in determining which fragments are currently displayed.
Demo: Supporting Fragments Across Activities
In this lesson, instead of using split activities we use separate activities.
The app looks the same as before in landscape, but when we change to portrait we have only the list of courses (no descriptions). This was a deliberate design decision that we see how to achieve it.
By the end of this lesson, when we choose a different course selection, the app takes us to a description of the course, and we can use the back button to get back to the course selection screen again.
Button Click Handling and Fragments
Jim says the button onClick attribute makes Fragment encapsulation difficult.
It is common to give our controls an onClick attribute, for example:
<RadioButton android id=”@+id/myRadioButton” android:onClick=”onTheButtonClicked” />
Jim explains onClick always looks for the containing activity, so if we use it inside the layout for a fragment, we have to put the onClick handling code in the activity, violating encapsulation.
So we want to avoid using the onClick attribute in our layouts.
Demo: Button Click Handling and Fragments
Jim demonstrates the issue he’s just described with the onClick attribute.
The app actually crashes! We see “Unfortunately, FragmentBasics has stopped.” and when we click OK the app disappears.
The app looked for the myButtonClickHandler method on the activity instead of the fragment.
We can fix by copying the method signature into the activity and writing three statements in there. It works but it’s convoluted and poorly designed.
Jim recommends giving up the convenience of the onClick attribute and explicitly implementing the View.OnClickListener interface instead.
We see exactly how to do this. Jim says the benefits of writing that bit more code far outweigh the loss of convenience that the onClick attribute gives us.