Welcome to part 3 of this review of the Pluralsight course Android for .NET Developers: 2 Building Apps with Android Studio 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.
This is the second course in a series of four courses which Jim has created for Pluralsight. I have also reviewed his first course which is Android For .NET Developers 1: Getting Started. If you are completely new to Android you should begin there. But if you have some previous experience with Android Development you can start here.
Views and Layouts
The role of Views and Layouts
The word Views is a generic name for all of our UI components: buttons, TextView, EditText etc.
Layouts are specialized ViewGroups which provide positioning information: identifying how the components inside it are positioned.
Jim says layouts often follow a layered approach, with one layout having another inside it, which has another inside of it, and so on.
We use relative positioning, or some other dynamic layout, rather than absolute positioning.
An alternative to using layout resources (which we saw in the previous module) is to do it in code, however Jim says layout resources are preferred and advises to describe the UI in code only when there’s no practical way of doing it with a resource.
Jim describes a previous project he worked on where that was the case and he needed to use code.
Layouts influence the positioning of Views, and the view layout is designed around hints.
As an example we see a diagram of a LinearLayout with multiple child Layouts and Views.
Using Layouts
Android supports a number of different layouts, and perhaps the two most popular are LinearLayout and RelativeLayout.
LinearLayout distributes Views in a horizontal or vertical line. We set the orientation property either to horizontal or vertical, and use hints, for example:
layout_gravity=left
layout_weight=1
Jim explains that we add all the weights together to get a total weight, and then divide it by the individual weights, for example if the total is 5, a weight of 1 has 20% of the available space.
RelativeLayout positions Views relative to other Views.
It is not mentioned in this lesson, but it’s important to know there is also the option of using WebView, which allows us to use HTML5, CSS3 and JavaScript.
If you have a team of web developers, it may be significantly cheaper if the team programs in their usual languages rather than needing to re-train in Android.
Having said that, part of the reason I am reviewing these courses is to help you to accelerate your Android learning.
The GridLayout was added at API Level 14 and creates a positioning matrix on the screen. Jim explains this in more detail here as well. It reminds me of Bootstrap‘s grid system.
Working with LinearLayout
We start with a very basic starter app in Android Studio, and create a layout resource with a vertical LinearLayout.
Jim shows us how to put three more layouts inside of this layout: a RelativeLayout, and two horizontal LinearLayouts.
He recommends dragging the layouts onto the parent view in the component tree.
Jim introduces the main layout:height settings: fill_parent, match_parent and wrap_content.
With a RelativeLayout added we set the weight of 2, and a height of 0. Yes zero! This means the LinearLayout will calculate the height to use.
With all the layouts added, we see the RelativeLayout, with a weight of 2, occupies half the space. The LinearLayouts, with a weight of 1 apiece, each take up a quarter of the space.
Jim adds Large Text to the bottom layout and sets the height to wrap_content. We also see that we can double click on the view to access the Id and text properties.
He explains the property layout:gravity affects the positioning of the View. We can either float it to the left or the right.
Some that’s initially a little confusing, is there is also another property called gravity. This affects the positioning of the View contents. For example the text within a view can be changed without altering the position of the view.
Working with RelativeLayout
When we drag a view into a RelativeLayout, we see information such as:
alignParentRigh, margin=107dp alignParentTop
We also learn about layout:margin which has options all, left, top, right and bottom.
Jim clicks on a resource button to the right of top, and we see dimension resources. These are resources that we use for spacing around our controls.
He chooses activity_vertical_margin for both views and the “click me!” button. and we see what this looks like in dimens.xml
Demo: LinearLayout and RelativeLayout
We see everything working. Jim saying dealing with layout is just a matter of practice.
Handling Event Callbacks with Interfaces
Unlike some .NET frameworks, there’s no automatic binding between the interface and the source code. We need to provide code to explicitly hook into the UI.
Jim writes a new method setupUiEvents, and calls it from onCreate in OtherActivity.java.
We get a reference to our button with findViewById, by passing in the id of our button, and casting the result to a button.
We then call setOnClickListener on our button. This accepts a reference to an OnClickListener interface implementation.
Jim says Java doesn’t have delegates. It uses interfaces instead.
The onClick method calls handleButton1Click, which is a new method we write. In this method we get a reference to our TextView and calling setText.
As Jim writes the code we see though bubbles comes up saying things like “Feels like we’re doing a lot of plumbing code” and “There must be a simpler way than this”.
He says there is a more elegant way.
Mimicking Delegates to Handle Event Callbacks
Jim says .NET delegates allow callbacks into object methods and that makes it very easy to pass callback objects around.
For a good explanation of delegates see Dan Wahlin’s course C# Events, Delegates and Lambdas.
Java doesn’t support delegates (even in Java 8). It does all of its callback handling work using interfaces. But we can fake them with Nested, anonymous classes.
A nested class is a class declared inside another class. Nested classes get a reference to the containing class.
Java also supports anonymous classes, which have a class instance, but no formal declaration.
That’s the theory. In the next lesson Jim show how to do it.
Handling Event Callbacks More Easily
In this lesson, the code is cleaned up considerably. The onClick method is removed altogether.
We create an anonymous class as our argument for setOnClickListener, and we see that Android Studio helps us by generating stubbed code for us:
theButton.setOnClickListener(new View.OnClickListener() {
@Overrride
public void onClick(View view) {
}
}
Inside onClick we can just directly call handleButton1Click or whatever our button click handling method happens to be.
Jim explains that if we wanted to we could also write it explicitly as OtherActivity.this.handleButton1Click.