
AppCompat v21 - Material Design for pre-Lollipop devices
- Transfer

On October 17, the Android 5.0 SDK was published, which brought new widgets and material design. We have expanded the support libraries so that you can use your latest developments on previous versions of Android. These changes include a major update for AppCompat , as well as the RecyclerView , CardView, and Palette libraries .
In this post, we'll take a look at what's new in AppCompat and how to use it to support material design in your applications.
What's new in AppCompat?
The AppCompat library (aka ActionBarCompat) appeared as a port of the new ActionBar API from Android 4.0 to devices with Gingerbread. She introduced a common API layer on top of a backported or standard implementation. AppCompat v21 brings the API and feature set from Android 5.0.
In this version of Android, a new Toolbar widget has appeared . It is a generalization of the ActionBar pattern and gives more control and flexibility. Toolbar is a view element in the general hierarchy, which simplifies the implementation of its interaction with other widgets, animations and reactions to scroll events. You can also use it as an Actionbar of your activity, which means that the standard elements of the action menu will be displayed in it.
You have probably been using the updated version of AppCompat for some time. This library has been included in updates to various Google programs released in recent weeks, including the Play Store and Play Newsstand. In addition, it has been integrated into the Google I / O app pictured above, which is open source .
Installation
If you are using Gradle, just add appcompat as a dependency in your build.gradle file :
dependencies {
compile "com.android.support:appcompat-v7:21.0.+"
}
New integration
If you are not already using AppCompat or starting from scratch, here's how to connect it:
- All your activities should inherit from ActionBarActivity , which in turn inherits from FragmentActivity from the v4 support library, so you can continue to use fragments.
- All your themes (which include the Action Bar / Toolbar) should be inherited from Theme.AppCompat. There are several options for themes, including a light one and a theme without an action bar (NoActionBar).
- When embedding something to display in a panel (for example, SpinnerAdater for navigation), make sure to use the context with the panel theme obtained with getSupportActionBar (). GetThemedContext () .
- You must use the static methods of the MenuItemCompat class to invoke MenuItem related actions.
For more information, see the Action Bar API Guide , which is a comprehensive guide to AppCompat.
Migration from previous versions
For most applications, now you need only one topic declaration in values / :
values/themes.xml:
Now you can remove all ActionBar styles from values-v14 + .
Themes
AppCompat supports new color palette attributes that let you customize the theme to your brand using primary and accent colors . For instance:
values/themes.xml:
When you set these attributes, AppCompat will automatically apply them as attribute values from API 21+. And this, in turn, will color the status bar and item in the list of recent tasks.
On older platforms, AppCompat emulates color themes when possible. Currently, this is limited to coloring the action bar and some widgets.
Tinted widgets
When you launch the application on a device with Android 5.0, all widgets are tinted with the color specified in the theme attributes. There are two main features that allow you to do this on Lollipop: drawable tinting and links to theme attributes (in the format ? Attr / foo ) inside drawable.
AppCompat offers similar behavior on earlier versions of Android for the following many UI widgets:
- Everything that is offered in the AppCompat toolbar (action modes and more)
- Edittext
- Spinner
- Checkbox
- Radiobutton
- Switch (use the new android.support.v7.widget.SwitchCompat class )
- CheckedTextView
You do not need to do anything on purpose to make it work. Use these elements in your markup as usual, and AppCompat will do the rest (with some caveats, see the FAQ below).
Toolbar Widget

Toolbar is fully supported by the AppCompat library and is fully consistent with both the capabilities and API calls, the widget from the SDK. In AppCompat, a toolbar is implemented using the android.support.v7.widget.Toolbar class . There are two ways to use it:
- Use as an ActionBar if you want to use the existing capabilities of the Action Bar (such as menu embedding, selection, ActionBarDrawerToggle , etc.), but at the same time want more control over its appearance.
- Use a standalone panel in situations where a regular ActionBar is not suitable. For example, to show several panels on the screen, occupy only part of the screen in width, etc.
Action bar
To use the Toolbar as an ActionBar, firstly, disable the regular ActionBar. The easiest way to do this is to inherit your theme from Theme.AppCompat.NoActionBar (or its bright version)
Secondly, create an instance of the toolbar. For example, by including it in your xml markup file
Height, width, background and more are now completely up to you, this is just a good example. Since the Toolbar is just ViewGourp, you can style and position it as you see fit.
Finally, set the Toolbar as an ActionBar in your activity or snippet:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.blah);
Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
setSupportActionBar(toolbar);
}
From now on, all menu items will be displayed in your toolbar, filled with standard menu settings calls.
Offline use
The difference between offline mode is that you do not set the Toolbar as an ActionBar. Therefore, you can use any AppCompat theme and you do not need to disable the regular ActionBar.
In offline mode, you can populate the Toolbar with content or actions. For example, if you want to show actions, you need to implement a menu:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.blah);
Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
// Set an OnMenuItemClickListener to handle menu item clicks
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
// Handle the menu item
return true;
}
});
// Inflate a menu to be displayed in the toolbar
toolbar.inflateMenu(R.menu.your_toolbar_menu);
}
There are many other things you can do with the toolbar. For more information, see the Toolbar API description .
Styles
Customizing the toolbar style is different from how it was done for the standard action bar. The style is applied directly to the widget itself.
Here is the basic style that you should use when you use the Toolbar as an ActionBar:
The app: theme declaration will make sure that the font and elements are using pure color (e.g. 100% opaque white).
Dark action bar
You can customize the toolbar directly using markup attributes. To make the Toolbar look like a “DarkActionBar” (dark content, light overflow menu), specify the theme and popupTheme attributes :
Search widget (SearchView)
AppCompat offers an updated API for the search widget that lends itself to more customization and styling. Now we use the style structure from Lollipop instead of the old searchView * theme attributes.
Here's how you can customize your SearchView style:
values/themes.xml:
You do not need to specify all (or even some) of the attributes. The default values should suit most applications.
Toolbar on the way ...
I hope this article helps get started with AppCompat and allows you to create amazing material-style applications. Let us know in the comments on the original article / Google + / Twitter if you have questions about AppCompat or any of the supported libraries, or where we can provide more documentation
FAQ
Why is my EditText (or another widget from the list above) not colored correctly on an Android device before Lollipop?
AppCompat widget tinting works by intercepting layout markup and inserting custom tinted widget versions. For most people, this will work correctly. But there are several scenarios when this does not work, including:
- You have a custom version of the widget (you inherited EditText)
- You create an EditText without using a LayoutInflater (e.g. by calling new EditText () )
Special tinted versions of widgets are still hidden, as they are in an unfinished state. This may change in the future.
Why doesn't widget X have a material style on non-Lollipop devices?
So far, only some of the most common widgets have been updated. Future releases will add others.
Why did my Action Bar have a shadow on Android Lollipop? I set android: windowContentOverlay to null.
On Lollipop, the shadow under the panel is created using the new lift API. To remove it, you need to call getSupportActionBar (). SetElevation (0) or set the elevation attribute value in the Actionbar style description.
Why is there no ripple animation on devices prior to Lollipop?
The main thing that allows RippleDrawable to animate seamlessly in Android 5.0 is the new RenderThread. To optimize performance on previous versions of Android, we left RippleDrawable overboard for now.
How do I use AppCompat with Preferences?
You can continue to use PreferenceFragment in ActionBarActivity when you run the application on a device with v11 + API. For devices with a previous version of the API, you will have to use PreferenceActivity, which is not stylized as a material design.
PS This is my first translation, please write in a personal letter about all inaccuracies (especially with regard to Russian terms)