Saturday, June 13, 2015

Bringing in the Android Design Support Library

In the recent release of the Android Support Library (May 2015), there is now a Design Support Library that implements more of the Material Design elements, e.g., snack bar.

Implementing the Snack Bar

First, we need to bring in the Design Support Library by adding the following to the dependencies in Grade Scripts > build.gradle (Module: app)

compile 'com.android.support:design:22.2.0'

Then we need to add the snack bar text to app > res > values > strings.xml:

<string name="snackbar_text">Hello</string>

Then we need to add a CoordinatorLayout (new in the Design Support Library) to app > res > layout > activity_main.xml:

<android.support.design.widget.CoordinatorLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"
    android:id="@+id/snackbarPosition">
</android.support.design.widget.CoordinatorLayout>

Finally, we implement the snack bar when clicking the "Hello" menu item in the toolbar in the MainActivity class.

if (id == R.id.action_hello) {
    Snackbar
            .make(findViewById(R.id.snackbarPosition), R.string.snackbar_text, Snackbar.LENGTH_LONG)
            .show();
    return true;
}

Friday, June 12, 2015

Building HelloAndroid

Building off the Getting Started training, here is the start of an implementation of HelloAndroid using best practices.

New Project

Using Android Studio (with target SDK version of 22), start a new Android Studio project with:
  • Phone and Tablet > Minimum SDK: "API 7: Android 2.1 (Eclair)".
  • Blank Activity (defaults)
Have to downgrade the build tools (bug in 23.0.0 rc1) by:
  • app (right click) > Open Module Settings > Build Tools Version: 22.0.1
Virtual Devices

Using Android Studio > Tools > AVD Manager, create three virtual devices:
  • Low Performance Phone
    • 2.7" QVGA (small, ldpi)
    • Gingerbread (Android 2.3.3 / API 10)
    • Chose armeabi (vs. x86); not clear if important.
  • High Performance Phone
    • Nexus 5 (normal, xxhdpi)
    • Lollipop (Android 5.0 / API 22)
  • Tablet
    • Nexus 7 (large, xhdpi)
    • Lollipop (Android 5.0 / API 22)
v7 Support Libraries

Using Android Studio, download the support libraries as documented.
Support Library Setup | Android
https://developer.android.com/tools/support-library/setup.html
Added appcompat Gradle Scripts > build.gradle (Module: app)
 
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.2.0'
}

Updated default AppTheme style to use the support library in app > res > values > styles.xml

<resources>
    <style name="AppTheme" parent="Theme.AppCompat.Light">
    </style>
</resources>


Then delete app > res > values > styles.xml (v21) get rid of the targeted AppTheme.

Switching from the Action Bar to the Toolbar

The toolbar is the recommended generalization of the Action Bar that is introduced in Android 5.0 / API 21 and is supported by the v7 support libraries.

First, we will update the menu to simply show "hello":

Update app > res > values > strings.xml to the following:

<resources>
    <string name="app_name">HelloAndroid</string>
    <string name="hello_world">Hello world!</string>
    <string name="action_hello">Hello</string>
</resources>

Then we need to update the app > res > menu > menu_main.xml to the following:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".MainActivity">
    <item android:id="@+id/action_hello" android:title="@string/action_hello"
        android:orderInCategory="100" app:showAsAction="ifRoom" />
</menu>

Finally, we update the MainActivity class' onOptionsItemSelected method as follows:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    if (id == R.id.action_hello) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

Now we are going to get rid of the action bar by editing app > res > values > styles.xml with:

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

Now we can put in the tool bar by adding the Toolbar style to app > res > values > style.xml

<style name="Toolbar">
    <item name="theme">@style/ThemeOverlay.AppCompat.ActionBar</item>
    <item name="popupTheme">@style/ThemeOverlay.AppCompat.Light</item>
    <item name="android:layout_width">match_parent</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:minHeight">?attr/actionBarSize</item>
    <item name="android:background">?attr/colorPrimary</item>
</style>

And we update the layout app > res > layout > activity_main.xml

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        style="@style/Toolbar" />
    <TextView android:text="@string/hello_world"
        android:layout_below="@id/toolbar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</RelativeLayout>

Finally, we need to update the MainActivity class' onCreate method to be:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
}

A small minor detail is to switch out the deprecated ActionBarActivity for the AppCompatActivity of the MainActivity class.

Using the Material Theme

The Material Theme can be customized using three colors: primary, primary dark, and accent (and the original window background) set as follows:

Updated app > res > values > styles.xml with colors:

<color name="primary">#AAAAFF</color>
<color name="primary_dark">#7777CC</color>
<color name="accent">#FF8800</color>
<color name="background">#DDDDFF</color>

and updated AppTheme:
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/primary</item>
    <item name="colorPrimaryDark">@color/primary_dark</item>
    <item name="colorAccent">@color/accent</item>
    <item name="android:windowBackground">@color/background</item>
</style>

Monday, June 1, 2015

Revisiting the Getting Started Training

In going through the Android Getting Started training, I observed a number of new key elements since Android 1.6 / API 4:
  • Action Bar: Introduced in Android 3.0 / API 11, the action bar is a navigation bar at the top of the screen that replaced the navigation functionality provided by the dedicated menu button (no longer required for Android devices).
  • Fragments: Also introduced in Android 3.0 / API 11, fragments were introduced to provide a flexible way to combine elements to support varying screen sizes, e.g., phones vs tablets.
Because we want to develop applications that run on virtually all Android devices in use (forces us to support versions Android 2.1 / API 7 or greater), we will be using the v7 Support Libraries that will provide these (and other) newer Android features.

Challenging Documentation (e.g., Action Bar)

One of the challenges in reading this (and other) Android documentation is that there are multiple ways of achieving the end, e.g., with and without the support libraries. While the multiple techniques are fundamentally the same, the devil is in the details and it is easy to get tripped up.

The action bar is an example of a particularly challenging implementation as it requires dealing with both the variation of the use or not of the support libraries and also the introduction of the Toolbar (generalization of the Action Bar) in Android 5.0  / API 21.