#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.
##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
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à!