From Punched Cards to Prompts
AndroidIntroduction When computer programming was young, code was punched into cards. That is, holes were punched into a piece of cardboard in a format...
Looking for a way to further polish your Android app on Lollipop? One option a lot of developers overlook is the Overview Screen.
As the developer docs state:
The overview screen (also referred to as the recents screen, recent task list, or recent apps) is a system-level UI that lists recently accessed activities and tasks. The user can navigate through the list and select a task to resume, or the user can remove a task from the list by swiping it away.
Before Lollipop, the Overview Screen was not configurable. Entries included the application label, launcher icon and a screen shot of what the user was last doing in the app.
With Lollipop, a more sleekly styled Overview Screen was introduced. More importantly, the new API enables you to customize the icon, title and top bar color of your application’s Overview Screen “card”:
With a little effort, you can ensure that your Overview Screen card shines amongst the rest.
Let’s first explore what happens if you rely on the built-in default Lollipop behavior for styling.
The system will pull values for the Overview card’s icon, label and top bar from your manifest:
These values will be pulled from the manifest entry for the activity at the base of the activity stack.1 In most cases, this means the values will be based on your launcher/main activity. If there is no value specified on the activity itself, the system will use the application level value.
An interesting thing to note is that the color of the label text is not configurable directly. Instead, the system automatically selects the text color based on the color used for the top bar. If the top bar is dark, the text will be light. Otherwise, the text will be dark.
The colorPrimary attribute was introduced in Lollipop. However, the attribute is available in the v7 appcompat library. If you have not already, you should make sure your app’s theme is Lollipop-compatible. An easy way to do this is include the v7 appcompat library and then base your theme on one of the Appcompat.Theme values, such as Theme.AppCompat.Light.
So when would this default behavior not be enough? That depends on how it looks with your app’s design.
One of the simplest, most impactful, things you can do to polish your app’s Overview Screen card is to provide a separate overview icon that looks great at a very small size and on the primaryColor background. Unfortunately, this usually cannot be achieved using XML.
Consider screenshots for my demo Big Nerd Ranch app:
Here is a snippet from the AndroidManifest.xml file:
...
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher_bnr"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.bignerdranch.android.bignerdranch.WelcomeActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
...
And here is the styles.xml file:
<resources>
<style name="AppTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">#747501</item>
<item name="colorPrimaryDark">#595a02</item>
<item name="colorAccent">#e7ad10</item>
</style>
</resources>
You can see the example icon is pulled from application android:icon, the label is pulled from WelcomeActivity’s android:label and the top bar color is pulled from AppTheme’s colorPrimary.
Kar Loong Wong, one of our awesome designers here at Big Nerd Ranch, took a look at my Overview card styling and immediately called out the inadequacies of using my launcher icon in the overview screen. Namely, the yellow does not show well at such a small size, so the propeller on top of the hat is too hard to see.
So I set off to specify a separate icon for the launcher activity. The problem is, the manifest doesn’t give you ability to specify the Overview icon separately from the activity icon. Setting an android:icon value on WelcomeActivity overwrites the launcher icon displayed. This means you will need another way to specify the Overview card styling. Lucky for you, there is another way…
Lollipop introduced the ability to set a TaskDescription on an activity at run time. Doing so will override the icon, color and label that the Overview card would otherwise get.
By default, the TaskDescription is based on the activity at the base of the task’s activity stack, as discussed in the XML section above. Other activities that pile on will not affect the styling, unless those activities have a TaskDescription explicitly set at run time. The topmost activity with a TaskDescription explicitly set will trump the styling specified in the manifest or in activities below in the stack with TaskDescriptions set.
The following code snippet from the WelcomeActivity.xml file builds and sets a task description for my app’s launcher activity:
public class WelcomeActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
TypedValue typedValue = new TypedValue();
Resources.Theme theme = getTheme();
theme.resolveAttribute(R.attr.colorPrimary, typedValue, true);
int color = typedValue.data;
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.ic_activity_welcome);
ActivityManager.TaskDescription td = new ActivityManager.TaskDescription(null, bm, color);
setTaskDescription(td);
bm.recycle();
}
}
...
}
Activity.setTaskDescription() is available only in API 21 (Lollipop). In order to support older devices while still showing the latest and greatest on Lollipop devices, it is important to guard your TaskDescription code with an API level check.
The code then uses the three-parameter version of the TaskDescription constructor, ActivityManager.TaskDescription(String label, Bitmap icon, int colorPrimary), to create an TaskDescription instance. Avoid the other TaskDescription constructors; they all ignore colorPrimary, which is rarely what you want.
I pass null for the label on purpose. If you don’t provide a label value, or provide a null value, the most-specific value available from the manifest is used (as discussed in the XML section above).
colorPrimary is pulled from the theme. This way, you don’t have to change the value in multiple places if your color palette changes. I recommend you use your colorPrimary value, unless you have good reason not to. It is also important to note that the primary color you specify must be completely opaque. If not, the system will throw a runtime exception.
Finally, call setTaskDescription(), which associates the TaskDescription instance with the Activity instance.
The end result looks like this, with separate launcher and Overview icons:
The Overview card is essentially a screenshot with a top bar drawn over top of it. It just so happens that the size of the top bar is the same size as the default Toolbar size. If your Toolbar is larger than the default size, it will hang below the top bar in the Overview card. If you do not have a Toolbar, your Toolbar is in a non-standard location or your Toolbar is smaller than the default size, your app’s screenshot will look clipped in the Overview screen.
Styling your app’s Overview card is one of the many ways you can polish the Lollipop version of your app. What other things have you tried? Stay tuned for more blog posts to help you get your app ready for Lollipop.
Many thanks to UX/UI Designer Kar Loong Wong for the icon assets in this post.
Not sure about tasks and the activity back stack? Check out our Android bootcamp to learn all the fundamentals necessary to be a solid Android developer. ↩
Introduction When computer programming was young, code was punched into cards. That is, holes were punched into a piece of cardboard in a format...
Jetpack Compose is a declarative framework for building native Android UI recommended by Google. To simplify and accelerate UI development, the framework turns the...
Big Nerd Ranch is chock-full of incredibly talented people. Today, we’re starting a series, Tell Our BNR Story, where folks within our industry share...