Skip to content

Instantly share code, notes, and snippets.

@degliwe
Last active August 29, 2015 14:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save degliwe/47ca967d0041cffade12 to your computer and use it in GitHub Desktop.
Save degliwe/47ca967d0041cffade12 to your computer and use it in GitHub Desktop.
How to theme Android wear watch face?

#How to theme Android wear watch face?

We will show here how to create a very nice and easy to implement theming system for your watchface.

Theme selector Theme Theme

##Prerequisite This tutorial is an extension to the excellent DigitalWatchFace sample project from Android developper https://developer.android.com/samples/WatchFace/project.html

##Build theme with xml resources.

###What is a theme? For this example, a theme is an array where each index correspond to an element of your watchface. Each index or slot, contain then a reference to a color.

So we will first create res/values/array.xml

<resources>
    <array name="theme_teal">
        <item>@color/color_black</item>            <!-- Background color-->
        <item>@color/color_white</item>            <!-- Main color-->
        <item>@color/color_teal_primary</item>     <!-- Secondary color-->
        <item>@color/color_teal</item>             <!-- Third color-->
    </array>

    <array name="theme_pink">
        <item>@color/color_black</item>
        <item>@color/color_white</item>
        <item>@color/color_pink_primary</item>
        <item>@color/color_pink</item>
    </array>
    ...
</resources>

In the snippet above, we've declared 2 theme (theme_teal and theme_pink). Each item reference a color in res/values/colors.xml

<resources>
    <color name="color_teal_primary">#009688</color>
    <color name="color_teal">#00796B</color>
    <color name="color_pink_primary">#E91E63</color>
    <color name="color_pink">#C2185B</color>
    <color name="color_white">#ffffff</color>
    <color name="color_black">#000000</color>
</resources>

###How do we list available themes?

Now we have themes referencing colors, but we have to provide an easy way to list all themes We can simply edit res/values/array.xml and add the following at teh end of the file

<resources>
    ...
    <array name="themes_list">
        <item>@array/theme_teal</item>
        <item>@array/theme_pink</item>
    </array>
</resources>

The array above simply list references to all existing themes We're done with xml editing now.

##Config activity

Theme selector

First we need to get the list of available themes.

MyWatchFaceConfig.java

@Override
protected void onCreate(Bundle savedInstanceState) {
  ...
    res = getResources();
    TypedArray themes = res.obtainTypedArray(R.array.themes_list);
  ...
}

During the onCreate(), we get the content of themes_list array from res/values/array.xml to TypedArray themes.

###Fill the listView

@Override
public void onBindViewHolder(WearableListView.ViewHolder holder, int position) {
    ColorItemViewHolder colorItemViewHolder = (ColorItemViewHolder) holder;

    //Get the resourceID for the theme at position
    int mThemeId = mThemes.getResourceId(position,0);

    //Get the theme array
    TypedArray mTheme = res.obtainTypedArray(mThemeId);

    //Get the main theme color (0=background,1=hands)
    int mainColor = mTheme.getColor(2, 0);

    //Set color for the bubble
    colorItemViewHolder.mColorItem.setColor(mainColor);

    //Store the resourceID of the theme (needed later)
    colorItemViewHolder.mSelectedTheme = mThemeId;
}

From that point, our ListView is populated by one colored circle for each of the themes in themes_list.

###Select a theme

We can now communicate the selected them by overriding the onClick()

@Override // WearableListView.ClickListener
public void onClick(WearableListView.ViewHolder viewHolder) {
    ColorItemViewHolder colorItemViewHolder = (ColorItemViewHolder) viewHolder;
    updateConfigDataItem(colorItemViewHolder.mSelectedTheme);
    finish();
}

in the snippet above, we pass the resourceID stored in colorItemViewHolder.mSelectedTheme to updateConfigDataItem(). We are done with the config activity.

##MyWatchFaceService.java

###Retrieve the selected theme

On MyWatchFaceService.java, we can get the selected theme resourceID and then extract the theme colors

        private boolean updateUiForKey(String configKey, int themeId) {
            if (configKey.equals(SensorFaceUtil.SELECTED_THEME)) {

                Resources res = getResources();
                //Get the theme array
                TypedArray mTheme = res.obtainTypedArray(themeId);

                setBackgroundColor(mTheme.getColor(0, 0)); //Background color
                setMainColor(mTheme.getColor(1, 0)); //Main color
                setShadowMainColor(mTheme.getColor(2, 0)); //Secondary color
                setShadowSecondColor(mTheme.getColor(3, 0)); //Third color
            } else {
                Log.w(TAG, "Ignoring unknown config key: " + configKey);
                return false;
            }
            return true;
        }

###Apply the theme to our WatchFace

We now have everything we need, the last part is just to update all the our Paint with the value from the selected theme.

        private void setBackgroundColor(int color) {
            mInteractiveMainColor = color;
            updatePaintColor(mBackgroundPaint, color);
        }

        private void setMainColor(int color) {
            mInteractiveMainColor = color;
            updatePaintColor(mHandsPaint, color);
        }

        private void setShadowMainColor(int color) {
            mInteractiveMainColor = color;
            updatePaintColor(mShadowPaint, color);
            updatePaintColor(mSecondPaint, color);
        }

        private void setShadowSecondColor(int color) {
            mInteractiveSecondColor = color;
            updatePaintColor(mShadowBasePaint, color);
        }

        private void updatePaintColor(Paint paint, int interactiveColor) {
            if (!isInAmbientMode() && paint != null) {
                paint.setColor(interactiveColor);
            }
        }

Voilà!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment