Android Application Development Cookbook(Second Edition)
上QQ阅读APP看书,第一时间看更新

Selecting theme based on the Android version

Most users prefer to see apps using the latest themes provided by Android. Now supports Material Theme is common for apps upgrading to Android Lollipop. To be competitive with the many other apps in the market, you'll probably want to upgrade your app as well, but what about your users who are still running older versions of Android? By setting up our resources properly, we can use resource selection in Android to automatically define the parent theme based on the Android OS version the user is running.

First, let's explore the three main themes available in Android:

  • Theme – Gingerbread and earlier
  • Theme.Holo – Honeycomb (API 11)
  • Theme.Material – Lollipop (API 21)

(As of writing this, there does not appear to be a new theme in Android 6.0.)

This recipe will show how to properly set up the resource directories for Android to use the most appropriate theme based on the API version the app is running on.

Getting ready

Start a new project in Android Studio and call it AutomaticThemeSelector. Use the default wizard option to make a Phone & Tablet project. Select the Empty Activity when prompted for the Activity Type.

How to do it...

Depending on the API version selected, Android Studio may use the App Compatability libraries. We don't want to use these libraries for this project since we want to explicitly set which theme to use. We will start by making sure we are extending from the generic Activity class, then we can add our new style resources to select the theme based on the API. Here are the steps:

  1. We need to make sure MainActivity extends from Activity and not AppCompatActivity. Open ActivityMain.java and if necessary, change it to read as follows:
    public class MainActivity extends Activity {
  2. Open activity_main.xml and drop in two views: a Button and a Checkbox.
  3. Open styles.xml and remove AppTheme as it will not be used. Add our new theme so the file reads as follows:
    <resources>
        <style name="AutomaticTheme" parent="android:Theme.Light">
        </style>
    </resources>
  4. We need to create two new values folders for API 11 and 21. To do this, we need to change Android Studio to use the Project view rather than the Android view. (Otherwise, we won't see the new folders in the next step.) At the top of the Project window, it shows Android, change this to Project for the Project View. See the following screenshot:
  5. Create a new directory by right-clicking on the res folder and navigating to New | Directory, as shown in this screenshot:

    Use the following name for the first directory: values-v11

    Repeat this for the second directory using values-v21

  6. Now create a styles.xml file in each of the new directories. (Right-click on the values-v11 directory and go to the New | File option.) For values-v11, use the following style to define the Holo theme:
    <resources>
        <style name="AutomaticTheme" parent="android:Theme.Holo.Light">
        </style>
    </resources>
    For the values-v21, use the following code to define the Material theme:
    <resources>
        <style name="AutomaticTheme" parent="android:Theme.Material.Light">
        </style>
    </resources>
  7. The last step is to tell the application to use our new theme. To do this, open AndroidManifest.xml and change the android:theme attribute to AutomaticTheme. It should read as follows:
    android:theme="@style/AutomaticTheme"
  8. Now run the application on a physical device or emulator. If you want to see the three different themes, you will need to have a device or emulator running the different versions of Android.

How it works...

In this recipe, we are using the Android resource selection process to assign the appropriate theme (which is a resource) based on the API version. Since we need to choose the theme based on the OS version in which it was released, we created two new values folders specifying the API version. This gives us a total of three styles.xml files: the default style, one in the values-v11 directory, and the last in the values-v21 directory.

Notice the same theme name is defined in all three styles.xml files. This is how the resource selection works. Android will use the resource from the directory that best fits our values. Here we are using the API level, but other criteria are available as well. It is very common to define separate resources based on other criteria, such as screen size, screen density, and even orientation.

The last step was to specify our new theme as the application theme, which we did in the Android Manifest.

There's more…

For more information on resource selection, see the Using designated folders for screen-specific resources topic in the previous recipe, Using graphics to show button state.