Testing in Android (MVP) – Part 3

In this last post of the three-part series on Testing in Android (MVP) we will go over how to add instrumentation tests that run on an Android device or emulator. If you have not checked out part 1 on unit tests or part 2 on integration tests, you should go back and check them out. Okay, let’s round off our series on testing in Android (MVP).

Setup your emulator for testing

In order to run instrumentation tests for our Android app we have to setup the emulator a bit differently than normal. When we run instrumented tests on an emulator of physical device we can’t wait for animations or network calls so we have to disable some animations.

Navigate to Settings | System | Developer options and disable all the animations.

If you haven’t enabled developer options, you can enable them by visiting Settings | System | About phone and tap the Build number until developer options are enabled. For additional reference visit the developer docs. Now that our emulator (or physical device) is all setup lets look at what dependencies we need to run instrumentation tests.

Dependencies in the app build.gradle file

Before moving forward we need to make sure to add the following testing dependencies to our build.gradle file to run tests with Espresso. Espresso is a UI testing framework for Android that allows us to find views and make assertions among many other things. For more information visit the link above but let’s focus on what dependencies we need to add.

Cool now let’s see what makes these tests useful.

Why Run Instrumentation tests?

Instrumentation tests will help us confirm our app shows data in a way that we expect based on our business logic. But wait… isn’t this what the integration tests do for our presenter? … Well yes, but instrumentation tests further confirm this since we can assert that a TextView contains some text, or that a Progress indicator is showing when data is loading.

Testing the View (Activity) from MVP

The first thing we need to do is create the test class. Let’s create a new Kotlin file and name it MainActivityInstrumentedTest.Kt. We need to add this into the androidTest folder of our project like so:

Next, let’s add a few annotations to the class. We need to tell the test runner we want to use the AndroidJUnit4 class so let’s add @RunWith(AndroidJUnit4::class) and then mark the test using @LargeTest annotation since we are running a large test. With all this setup we should have the following test class setup:

Finally, let’s create a rule for our test to launch the MainActivity by adding the following line:

Alright, we are all set up so let’s write our first test:

Perfect, you have written your first instrumentation test. Let’s press the run button next to the new method and see the green bar!

Nice work! Now let’s move on to the more difficult tests with the implementation of our custom keyboard.

Custom Keyboard instrumentation Example

Testing a custom keyboard is a non-trivial task so let’s see how we can do this. Well with any custom keyboard we need to use Espresso ViewMatchers to find our keyboard and then perform an action based on X and Y coordinates since we can’t find the views on the keyboard using their respective ids. So how does this look for our test?

Well, first let’s add a few helper functions for this to our test class. In the code snippet below we are adding a new method to click at an x and y coordinate within the view we have matched against (more on this in a bit). So here is what the code looks like:

It is important to note here the view we have, and the x and y position is relative to the View and not the entire screen. So we define the touch points in terms of the view we are matching against. Let’s look at the other helper method we need to add:

This method uses our keyboard default width percent and the row count to determine the coordinate x and y we want to press in the KeyboardView. Awesome so now let’s check out the test function to enter a price and hit the check button on the keyboard.

In the code above, we have called our getTargetXAndY() helper funtion and determined the point we want to single tap. From that target point we can interact with the other helper method clickXY passing in these target X and Y coordinates to hit the check button. Lets run the test and see that we can confirm we enter the price and then hit the check button.

Great job! We are finally done with our instrumentation testing for our tip calculator. The following is the end result with both the test method and the two helpers for full reference.

For additional content related to these keyboard tests check out my question and answer on StackOverflow.

Summary

Great job! You have just learned how to add instrumentation tests to your application and confirm the behavior of your application by using Espresso to assert that views on screen display the expected results when a tip is calculated. The full code for this tutorial is available on GitHub. This wraps up our 3 part testing series for MVP architecture within an android application.

If you enjoyed this tutorial please like, share or follow me on social. Don’t hesitate to leave a comment with any feedback!

 

Testing in Android (MVP) – Part 2

Integration Testing

Integration tests are important in Android so we can ensure the behavior of the integration between the view and the model work correctly. So how exactly do we write these integration tests since the presenter relies on 2 other objects the View & Model?

In the previous post, we added a new dependency to our project called MockK. What is MockK? Well, MockK is a mocking framework for Kotlin. A mocking framework allows us to verify the behavior of an object without having to build the objects from scratch among various other things.  More information about MockK can be found at the website.

So now we know about mocking frameworks let’s see how we use them to build out integration tests.

For brevity, I am only going to show how we use the mocking framework to write the integration tests although you can find the source code for the MainPresenter at the github page.

Annotations

Alright, so what have we done here?

With the property fields, you will notice some annotations, @RelaxedMockK, @MockK. These annotations provide use with mocked version of the classes they sit above. For example, @RelaxedMockK on the Contract.View class is setting up a mock object that is relaxed in nature.

From the docs:

Relaxed mock is the mock that returns some simple value for all functions. This allows to skip specifying behavior for each case, while still allow to stub things you need. For reference types chained mocks are returned.

Source

The @MockK annotation creates the standard version of the mocked object. This means we want to mock the class but will provide the behavior of the class when interacted with, however, we are passing it a parameter relaxUnitFun which tells the framework to allow functions returning Unit to be relaxed. In our case, this affects the setTipOption function which has no return value or Unit if you prefer to be explicit.

from the docs:

In case you would like Unit returning functions to be relaxed. You can use relaxUnitFun = true as an argument to mockk function, @MockKannotation or MockKAnntations.init function.

Source

Although we only use these annotations, MockK provides many other useful annotations that are worth looking into.

The Setup

Okay, so now that we have understood a bit about the annotations we are using let’s turn our attention to the setup method:

Here we, initialize the mocks and set up the model to return the values we want to use when interacting with the mock. Additionally, we tell MockK to init the annotated classes from above. Since this method is annotated with @Before it will run before every test is executed.

The Tests

These two tests that we set up above allow us to ensure the behavior of the start method in our presenter as well as the changeTipPercent method. We then use the verify lambda from MockK to assure the view has been interacted with in an expected way. That’s it! You now know how to use MockK to write a simple integration test. What happens though when we want to adjust the behavior of a mock after setup occurs?

Changing behavior with every

Each of the above methods has a line:

This line is altering the behavior of the computeTotalPrice function of our model so we can verify the other methods of the view are interacted with in an expected way. We can now verify that the displayFinalPriceWithTip function of the view is called as well as the displayError method when we pass in a bad value.

Summary

Wow, look at you go! You now know how to create an integration test for your presenter in the MVP architecture using MockK. In the last part of this testing series with the MVP architecture we will take a look at the instrumentation tests on Android for running tests on an Emulator or physical device. See you then!

If you enjoyed this post please leave a comment, like or share, and follow me on social media.

Testing in Android (MVP) – Part 1

In this first post of a three-part series, we will walk through unit testing an android application that uses the MVP architectural pattern. By the end of the three-part series, we will have discussed unit testing, integration testing, and instrumentation testing. The first two will allow us to run tests very quickly on our local development machine. For the third, we will need to set up an emulator or use a physical device to run the tests. This series will both show you the benefits of having chosen the MVP pattern as well as the various libraries and frameworks that help us write tests against this architecture.

Jumping Right In

Picking back up with the MVPDemo from the previous post, where we built a Tip Calculator app, we are now going to test our code.

Test our code? But that’s a waste of time, we have to ship!

With automating our unit tests we can provide:

  1. scale
  2. insurance
  3. peace of mind

In other words, with automated unit tests, we can ensure the code that we wrote last week does the same thing this week, even if someone else has committed a new feature.

The two-thirds Rule

In Android, we should test at least 2 out of the 3 things from the list below to ensure that our app’s core functionality works:

  • Unit tests – the smallest possible test we can write which asserts an actual value matches an expected value.
  • Integration tests – tests that ensure the proper integration of 2 or more components. (think presenter in the MVP pattern)
  • Instrumentation tests – tests that run on a physical or emulated device. These are not fast tests but they can be useful in a CI system or if you want to make sure things display as expected (asserting views are on screen or contain certain text, clicking this button performs this action, etc.).

Okay so now that we know the types of tests we should be writing let’s ask the real question…

Is there really a two-thirds rule?

Well, no. The point is you should consider covering the majority of your code with some tests. Being able to confidently know that two-thirds of the behavior of the code you have just written is guaranteed will drastically improve your process as an engineer and team member.

In my previous post, discussing the MVP architectural pattern, we can see how the decoupling of our code allows us to more easily test the functionality within our app. Specifically, we can see how the three test types we just mentioned apply to the MVP pattern.

As you can see, we can test the model with fast unit tests using either JUnit , AssertJ or Robolectric. We can test our presenter using a combination of AssertJ & MockK (Mockito if you prefer it too MockK). And finally, we can test our view code using the Espresso library or UIAutomator . These are just a subset of the popular testing frameworks available to us now but let’s get to the unit testing for this first part.

Setup

Before we get started we have some setup to take care of to import the correct dependencies for testing. In the top-level build.gradle file, add the following line (e.g denoted by the // 1):

and in your app level build.gradle file add the lines (e.g denoted by // 1, // 2 // 3):

  1. Adds the plugin for JUnit 5 to work with Android
  2. Adds the test/kotlin directory to our test source sets
  3. Adds the JUnit 5, AssertJ and MockK testing dependencies

Writing a Unit Test

One of the most important areas to test within our code base is our app’s model code. No, I am not talking about testing a POJO or POKO (Kotlin variant), I am talking about the Model used to manage the data within our application! The code that determines the actual behavior of the functionality provided for a view. We have to test this code to guarantee our app works as expected. But what does this look like?

MainModel code (for reference):

Looking at our model code we see it provides the following functionality for use:

  • MainModel() (default constructor)
  • setTipOption(position: Int) : Unit (sets the tip option and returns nothing)
  • computeTotalPrice(price: String?): Double (computes the price returns total)

Since we don’t have any constructor arguments lets start by assuring the setTipOption code works as expected. We want to assert that with a valid index, the tipOption is set to the expected value.

Okay, so what did we just do? Well, we set the tip option to 0 (the first index of the array in our model) which sets our tip to 5% so when we compute the total price of $100 check, we should expect that we get back a value of $105.0 for 5% of $100 = $5.

We have written our first passing test but if we run the same test with code coverage we will notice that we haven’t tested the full source code for this method. So, let’s take a look at one other test case: the invalid tip option. If you look back up at the MainModel code, we can see that if the index of the argument is out of range of valid tip options we default to a 20% tip. We will want to make sure that code works too!

Okay perfect all code within the setTipOption method is now covered and the behavior works as expected. Going forward, if any of the code in this method changes we now have a couple of tests to make sure we don’t break the expected behavior. If we do break the expected behavior (assuming a new feature or new default is chosen by the product team…), we will update the test case and move on. Additionally, we want to test out the functionality of the computeTotalPrice method.

Since this method is a bit more complicated we have to test it with at least 3 tests:

  1. Test that a good price will yield the expected result
  2. Test null or empty price yields 0.00 return value
  3. Test if we have a negative price that all values will be 0.00

Well done! 100% test coverage for a single class and the best part is in under 1 second we can now test that the MainModel code works as expected. As an exercise, write some tests to exhaust the tip calculator options testing the remaining percentages return the expected values.

All of the source code can be found on GitHub.

Summary

Great job! Now you know how to write unit tests that guarantee the behavior of your tip calculator’s model code. In this post, you have learned that there are 3 types of tests you should consider when it comes to Android application development. You have learned about some of the frameworks used in the testing process. And you have written your own unit tests.  In my next post, I will show you how to test the presenter code in the MVP pattern to guarantee the integration between the View and Model.

If you enjoyed this post please share or comment! And feel free connect with me on social media.

 

Manageable Dialogs in Android

Why are dialogs so difficult?

Using Dialogs in Android has always been a bit of a pain. In our apps, we tend to have various kinds for different things resulting in tons of lines of code for such a simple purpose. When we need the user to know about something in our app or that an error occurred we show an AlertDialog. For business decisions it may require that a network request needs to block the user from doing anything but wait, so we show a ProgressDialog (now deprecated). Additionally, if we need to request permission for something dangerous (i.e. versionCodes >= 21) we do that. And then in more complex cases we ask the user something and have them perform an action by pressing one of three buttons (positive, neutral, negative), provide a list of options either single choice or multiple, or even collect input from the user. As you could imagine (or may have experienced before) this can lead to tons of the same code doing slightly different things littered throughout your codebase.

This can become a real problem when we need to update certain aspects of the dialogs within our application such as the theme or maybe we were previously using cancelable dialogs and now we want them to not be cancellable. This could become a large task consuming valuable time! As creative engineers and proponents of object-oriented programming, however, we have managed to get around this by introducing our own version of boilerplate to solve these problems using static methods within a utility class. This can make these changes much easier and provide a reusable set of methods for other projects.

For example, the following DialogUtil.java class has multiple ways of showing dialogs in java using this pattern:

So great! Now we have a utility class we can leverage for any project in which we need to display dialogs. It is easy to make any changes in this utility class if we need to update our apps dialogs preventing us from having to open various files to update each dialog one by one. Although this isn’t perfect it is much better than the alternative. Using this utility class we can show a dialog like so:

The alternative without that wrapper class shows why it is more preferable to wrap the methods:

Could you imagine searching for this code in your project and changing R.style.AppTheme_Dialog to something else for every instance (of course we could use find & replace with modern IDEs…), rather than opening the utility class and updating a single place?! (I can’t!) However, we choose to wrap the functionality using Java doesn’t matter too much because, with the introduction of Kotlin, we now have a better way to incorporate dialogs into our codebase with much less boilerplate.

A better approach with Kotlin

The Kotlin programming language treats functions as first-class citizens. From the Kotlin docs:

Kotlin functions are first-class, which means that they can be stored in variables and data structures, passed as arguments to and returned from other higher-order functions. You can operate with functions in any way that is possible for other non-function values.

But what does this mean for Dialogs?

Well, instead of including listeners within our activities or directly in our DialogUtils class (see above) we can just pass a function as a parameter to one of our utility functions in Kotlin making our code even more readable.

With a custom extension function on the Context class, we can create the same Dialog with a list and a single choice option style using the sample from Util.kt :

and then its usage from MainActivity.kt:

The best part is we can now use any class that inherits from Context and this displaySingleChoiceDialog method is available to us!

Or if you like the popular library Anko you can do the same thing:

Don’t forget to add the following dependencies to your build.gradle file if you like Anko better:

Summary

Working with dialogs in Kotlin is much easier than doing the same in java. Since functions in Kotlin are first class we can move all the boilerplate for our dialogs into a common utility file and then use lambdas to handle the actions performed on the dialogs within our activities.

NOTE: with Kotlin’s null safety we could extend a single function in a utility file to handle the building of any dialog we want!

If you enjoyed this article or have a comment about an error please leave a comment.

Also, don’t be a stranger and follow me on social media!

Best practices MVP in Android

Working with GUI applications is a lot of fun for a developer. We get to influence design and user experience as well as the end product for any given feature. This can be fun until a designer comes over and shows you something you know will be entirely custom or better yet, it is a complete redesign but you haven’t spent any time building an architecture in your company’s app. Uh oh! Get ready to cancel all your prior engagements, late nights and long days await. It doesn’t have to be like this though.

In most of my apps, I prefer to use the Model View Presenter (MVP) pattern although MVVM is basically the same idea (I am not talking specifically about the ViewModel from architecture components… but you can read more about that in my previous blog post). Okay, so what am I talking about.

Well, in the MVP pattern we have our three layers again:

  • Model – controls how we access and manage the data in our application
  • View – controls how we display that data in our user interface
  • Presenter – acts as a middleman between the view and the model

Alright great! Now we know what the three pieces are but how do we go about making this a real thing in our app? We are going to build out a simple tip calculator application using the Kotlin programming language and the MVP pattern.

Okay, so we see that when an action is performed via the user interacting with the view, the presenter uses its knowledge of the model to have it perform an operation, return the result and then display it back in the view. Let’s take a look at how we can adapt our code base to this pattern more closely though.

When designing the MVP pattern we should really consider what does our application need to do in terms of functionality. Since we are building a tip calculator this will be relatively simple to figure out.

With our Model we want to allow the following functionality:

  1. Set check amount
  2. Set a tip amount
  3. Compute the total price of the check including the tip

With our View we want to display the following:

  1. A TextInputEditText to collect the check total
  2. A ChipGroup with Chips to allow the user to choose a tip percentage
  3. A FloatingActionButton for the user to press to compute the total with tip
  4. An AppCompatEditText to display the total
  5. An AppCompatEditText to display the tip amount

And finally, with our Presenter we want to:

  1. Setup the initial View state
  2. Pass the tip percentage to the model when a Chip is checked
  3. Pass the check amount to the model and compute the cost of the total check with tip
  4. Tell the view to display the total and the tip amount

Now that we have the important stuff laid out we can start building out the different layers of the application.

The View is comprised of our MainActivity. Since we are developing a testable architecture though we will use interfaces to define the contract for the View and the Presenter. This may seem unnecessary now but in a later post, we can see how this architecture allows us to test our app on a JVM. We can start with the following Contract interface which wraps these two other interfaces like so:

 

Now let’s implement the interface and add the code for all the widgets to display the data from our presenter layer in our View.

Now since the MainActivity creates the Presenter lets look to see how it manages the View and Model as a middleman:

Finally, we can look at our Model code which handles the business logic of our application:

And that’s it! We have an app that uses the MVP architecture in the Kotlin programming language. As you can see the View is pretty dumb in that all it handles is displaying things to the user based on our presenter interacting with our mode. The best part about this architecture is that you can test it very easily which I will show in an upcoming blog post!

Please comment or share on social if this was helpful!

 

 

Adding PopupMenu to an adapter item

In Android, lists tend to have actions associated with them. We can do this via onClick(View v) or event the outdated long press action, but what if we want to give an item in our list a menu style drop-down? Well, this is actually pretty easy to do with the PopupMenu class from Android. So how do we use it?

Since I have received a lot of traffic on my StackOverflow post about just this thing, I have decided to share a quick tutorial on how to add them to your adapter.

Piggybacking off the same repository from our ViewModel and LiveData demo we can easily add a drop-down menu via the PopupMenu class.

First, let’s add the following strings to our strings.xml file:

Then let’s create a menu using these values as our titles:

Next, let’s add a new overflow image button using vector assets:

We are almost done, now we just need to add an AppCompatImageButton to our layout:

Now let’s hook it all up to our adapter code in our onBindView(holder: ViewHolder, position: Int) method!

And there you have it! Your list items will now have a PopupMenu where you can react to the list items overflow button.

Please leave a comment or share if you enjoyed the tutorial.

The full source code is available on Github.

 

Using ViewModel and LiveData in your Android App

A common trap

Since the dawn of Android, application development has been a bit like the wild west. As developers, we want to build fast so sometimes we neglect the architectural design of our applications from the start. A designer hands off the UI and we go over the requirements for our project and start building. The MainActivity starts out lean but we create a bunch of objects for our business logic, hook into framework API’s to start services or leverage hardware from the device resulting in a 2K line file and error-prone code. But we can do much better by taking some extra time to think about separation of concerns within our application. The applications we are building should be modular, extensible and testable. So how do we accomplish this in GUI applications?

Loaded answer: developing an architecture for the application!

Popular GUI architectures:

All these patterns encompass similar concepts. The main idea is we have a Model that contains our business logic, which will be mostly Android agnostic so we can test the code we are writing without the framework dependencies. We have a View that is responsible for displaying information to the user and handling interactions from the user with the on-screen widgets. Finally, we have the ViewModel which is responsible for the display logic for our model (business logic) into the view. But what does that actually mean?

Things may become clearer with the following diagram:

The View is responsible for loading the layout, attaching listeners to UI elements as well as hooking into Android Framework APIs such as system services, custom service implementations, broadcast receivers, etc. Depending on the design choices the view will also be responsible for injecting dependencies or creating the dependencies for the other components in the design.

The ViewModel is responsible for facilitating communication between the view and the data access layer containing application state and business logic.

The Model will handle everything else related to the business decisions of the application including remote connections to REST APIs, data persistence for offline scenarios, and anything else that could be a business rule for the application.

Hopefully, this clears things up for now but if not don’t worry we are going to work through an example.

App Scenario

Let’s think about how we can accomplish the following task: Build an app that lets me search for places using a textual phrase using Google’s Places API. Cool project, I know! But how do we design this in a robust way?

Architecture Components!

In GUI applications there are plenty of design patterns to improve the design of our applications such as MVP, MVC, MVVM, as well as a few others. It has not always been easy to decide which to use when and there is certainly no silver bullet. It has become a common idiom though to use however, we have seen best practices emerge over time in building great apps from developers among the community and open source projects from companies across the world. It was only recently that Google took a stab at actually providing some built-in APIs on Android to help guide the architectural structure of our applications via Architecture Components but wow are they useful.

For our purposes, we are going to look into three components from the new libraries but only one will be the main area of focus.

  1. LifecycleOwner
    • Since the latest release of the support library, we now have activities and fragments implementing the LifecycleOwner interface. So we won’t have to worry about this too much for now but it is important to know it is needed for the ViewModel.
  2. LiveData/MutableLiveData
    • LiveData and MutableLiveData are generic data holder classes that can be observed within a life cycle. Remember LifecycleOwner? These objects allow the data they hold to be observed when changes are made. The distinction between the two, however, is that MutableLiveData exposes the setValue(T) and postValue(T) methods. This means we can change the underlying value and the UI will reflect those changes automatically if we attach an observer in which we update the view. There is also a way to attach an observer without a LifecycleOwner which you can read more about here but we won’t focus on that here.
  3. ViewModel (main area of focus)
    • ViewModel is a class that is responsible for preparing and managing data for an Activity or Fragment. It is where a developer can hook into the business logic and the best part is data outlives the life cycle of the Fragment or Activity it is used within. This means objects are not recreated everytime the screen rotates or your app is backgrounded(unless of course, the system kills your app to free up resources).

Architecture

So we have thought a little bit about the architecture of our app and we will implement the following:

  • Search screen to get user input through a form field
  • Search result screen to display the results
  • Detail screen to display more information about a search result
  • A repository which will make HTTPS request to the Google Places API using Retrofit
  • Business logic class (ViewModel) which will use the repository to get data and manage it

All source code is written in Kotlin and available on Github.

Let’s skip over the easy parts since we already know how to collect input from an EditText and pass it as an extra through a Bundle to a Fragment.

The Search Results Screen layout xml:

The important parts of the layout really are the Toolbar and the RecyclerView everything else is meant to improve the UI/UX.

Place List Fragment:

Note: important information is in the comments above. If you looked through this code you will notice using the MainViewModel we were able to request the places using the query from the extras and search the places API. We also attached a listener which allows us to update the UI when the request finishes.

Place Detail Fragment

If the comments weren’t enough the important thing to note here is since we are attaching the MainViewModel to the hosting activity of these two fragments we viewed the source of above we only need to re-attach to it and our data is still there. This means we can navigate to and from the same place from the list or list of places and the data will persist.

And finally, the MainViewModel

In the MainViewModel we have all our business logic nicely separated from the rest of our application. The MutableLiveData holder class around our PlacesResponse and PlacesDetailsResponse allow us to observe the changes applied to them when the rest call finishes.

Summary

As you can see LiveData and ViewModel are very powerful components that can help build better apps. Hopefully, this shows how powerful the LiveData and ViewModel classes are and convinces you to at least look into using them to help architect your application. In an upcoming tutorial, I will show you how we can test this code easily.

Please leave a comment or share if you enjoyed the tutorial.

Navigation with Architecture Components

Android JetPack

Android Jetpack was announced this week at Google IO 2018 and it is something you should definitely direct your attention towards. In an effort to save developers time, the only resource we have a finite amount of, the Android team has prioritized making it easier to get started building great apps with a collection of libraries that streamline your development flow. The libraries cover four key areas of application development:

  • Foundation – AppCompat, Android KTX, Mutlidex & Testing
  • Architecture – Data Binding, Lifecycles, LiveData, Navigation, Paging, Room, ViewModel & WorkManager
  • Behavior – Download manager, Media & playback, Notifications, Permissions, Sharing & Slices
  • UI – Animations & transitions, Auto, Emoji, Fragment, Layout, Palette, TV & Wear OS by Google

As you can see there are a vast number of important topics bundled into this set of libraries to improve developers lives. Additional information can be found at the developer site.

Fragments Again?

This year at IO the android team presented a lot of talks about all the new features that have been developed under the Jetpack umbrella and even more specifically architecture components. With the release of Navigation in architecture components, Google is once again advocating for the use of Fragments within your apps. And, get this they are pushing for single Activity apps if possible having Fragments do the bulk of heavy lifting leaving only things such as top-level navigation and app chrome for the Activity to handle.

Google spent a lot of time digging into Fragments and listened to developers feedback to solve their biggest pain points through these new architecture components. Today we are going to look at one of the new offerings in architecture components, Navigation.

Getting started

Prerequisite – understanding of Android application development and the Kotlin programming language.

All the source code is available on GitHub.

Head over to the Android Studio download site to get the Android Studio 3.2 Preview to get started using Jetpack. Once installed, create a project that includes Kotlin support and adds an Activity via the new Activity & Fragment + ViewModel option.

Okay, that should have created 3 things:

  • MainActivity
  • MainFragment
  • MainViewModel

Next, open up the app/build.gradle file and add the additional dependencies:

Now we should be all set up. If there is an issue with the Kotlin standard library change:

to

MainViewModel

Let’s start with the source of our data for the list of produce products we will display in our sample app. Remove any code from the generated sample class and replace with the following:

As you can see, we are using the new ViewModel architecture component in our MainViewModel but since we are looking into Navigation, I will cover ViewModel in more detail in another post. Next, let us take a look at the MainFragment.

MainFragment

The MainFragment is the home screen of our app hosted within a single Activity.  It will show a list of produce products to the user and listen for items being tapped from the DataAdapter class. When onClick(item: String) gets called we will use the new Navigation architecture component to show the DetailFragment.

In MainFragment we want to do 4 things:

  1. Initialize our MainViewModel
  2. Setup our RecyclerView
  3. Initialize our Adapter
  4. Implement DataAdapter.Listener

The following code shows just this:

As you can see, in the onClick(item: String) method something interesting is happening. We see no FragmentTransaction but when we run the app tap on an item in the RecyclerView we see our DetailFragment loads with no issue. So what exactly is happening here?

Google added a new way to navigate using fragments without the developer ever needing to deal with FragmentTransactions again. Through the static NavHostFragment.findNavControllerMethod(this) call we obtain a NavController from the new NavHostFragment class, more on this shortly. Once we have our NavController we can call navigate() with either and id from our actions, again more on this in a minute, or passing id with a Bundle. So what is this NavHostFragment?

MainActivity

Before answering this let’s first look at the layout file.

Inside our main_activity.xml, you will notice there is a static fragment placed below the Toolbar within the ConstraintLayout. The fragment has a few things we have not seen before:

NavHostFragment is a new class that helps orchestrate the navigation among fragments, but let us look closer at the other 2 new methods.

  1. app:navGraph is a new attribute that points a file in a res/navigation folder, which contains some XML to describe what the NavHostFragment should do when certain NavActions are performed.
  2. app:defaultNavHost allows us to specify this fragment as the default navigation host allowing it to stick on the top of the stack for this NavController.

So what exactly is this nav_graph.xml file?

The navigation graph is a new XML configuration file for setting up a navigation host and it’s NavController using the new navigation editor in Android Studio 3.2. The following XML sets the MainFragment as the starting point and attaches an action with an animation to the destination of the action, the DetailFragment.

Let’s now look back at the MainActivity code and finish up by explaining the power of the Navigation library.

MainActivity

Inside the MainActivity we want to do 2 things:

  1. Set the toolbar as the supportActionBar and add support for back navigation via the NavHostFragment’s NavController
  2. Override onSupportNavigateUp()

In the example, the ActionBar gets linked to the NavHostFragment’s NavController and then the Activity overrides onSupportNavigateUp() to handle back navigation through the same controller. Wow! That was so easy now we have a single Activity app with a list and a DetailFragment. The NavHostFragment manages the loading of the MainFragment and DetailFragment when the respective NavActions are taken via the view elements of our app and the MainActivity is merely a shell for the up navigation and common chrome.

If you found this post helpful please like or share on social networks. Please leave a comment if you find any mistakes in the snippets or consult the github code for a full implementation.

Welcome to my blog!

Intro

Hello World! My name is Kyle Jablonski. I am an Android developer and Software Engineer in San Francisco, CA who wants to get involved in the community more so I have started this blog to share information about Android development. I have been working on Android now since 2011 and feel that it would be a waste to not give back to the community and create value for other android engineers seeking more information. So let’s get started.

Background

Since I have been working on Android many things have changed in the framework. We have gone from having little standards to having tons of them. I remember working on Android’s Gingerbread offering in the early days when creating dynamic UI’s was not a priority and tablets where not yet part of the ecosystem. Since then we have seen major improvements in the way we can build great app’s which started with the release of Honeycomb to support larger screens. At that time, the UI/UX of Android was certainly improving although when Fragments were introduced we saw a lot of opinions about them.

In each subsequent release, Ice Cream Sandwich, Jelly Bean, KitKat, Lollipop, Marshmello, Nougat, Oreo & now Android P (in beta) we have seen that our lives as Android developers have become much better. We can now use design languages like Material design to create fantastic looking user interfaces and some features from Java 8! Wow, what a vast improvement from the early days. And now we have the ability to write our apps in an even more fluid way using Kotlin!

The Future

With the announcement at Google IO 2017 that Kotlin is a first class language for Android we have seen a major adoption of the language and developers are extremely satisfied with it. Google continues to support the language an offer easier ways to do things in Kotlin with the new Kotlin KTX. With the most popular mobile operating system in the wild today, we are positioned in a unique spot to impact the globe with our apps.

Now with an ongoing Google IO 2018, we have seen even more improvements with features such as Android Jetpack to help build apps quicker, Slices to get our most used portions of our UI out in front of our users in a more seamless way. We have seen a major update to the developer console that now allows us to create Android app bundles to create smaller downloads to reach a larger market. For a list of all the features released at Google IO check out the android developer site.

With that said Welcome to kdotj.com!