Thursday, November 6, 2014

Android : Usages & Issues of Toolbar (Material Compatibility) in Appcompat 21

Toolbar Widget

Toolbar is fully supported in AppCompat and has feature and API parity with the framework widget. In AppCompat,Toolbar is implemented in the android.support.v7.widget.Toolbar class. There are two ways to use Toolbar:
  • Use a Toolbar as an Action Bar when you want to use the existing Action Bar facilities (such as menu inflation and selection, ActionBarDrawerToggle, and so on) but want to have more control over its appearance.
  • Use a standalone Toolbar when you want to use the pattern in your app for situations that an Action Bar would not support; for example, showing multiple toolbars on the screen, spanning only part of the width, and so on.
Toolbar supports a more focused feature set than ActionBar. From start to end, a toolbar may contain a combination of the following optional elements:
  1. A navigation button
  2. A branded logo image
  3. A title and subtitle
  4. One or more custom views
  5. An action menu

Things to do remind while Implementing ToolBar

IllegalStateException (windowActionBar)

java.lang.RuntimeException: Unable to start activity ComponentInfo{}: java.lang.IllegalStateException: This Activity already has an action bar supplied by the window decor. Do not request Window.FEATURE_ACTION_BAR and set windowActionBar to false in your theme to use a Toolbar instead.

Solution:

add
 <item name="windowActionBar">false</item>  
in theme.

Apply Styles for Version above API level 14+


   <color name="holo_blue_light">#ff33b5e5</color>  
   <color name="green">#36A245</color>  
   <color name="ripple_material_light">#40000000</color>  
   <style name="AppBaseTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">  
     <item name="windowActionBar">false</item>  
     <item name="colorPrimary">@color/holo_blue_light</item>  
     <item name="colorPrimaryDark">@color/green</item>  
     <item name="colorAccent">@color/ripple_material_light</item>  
   </style>  

Above 21+


   <style name="AppBaseTheme" parent="android:Theme.Material.Light">  
     <item name="windowActionBar">false</item>  
     <item name="colorPrimary">@color/ripple_material_light</item>  
     <item name="colorPrimaryDark">@color/green</item>  
     <item name="colorAccent">@color/holo_blue_light</item>  
   </style>  

Styling of ToolBar:

Styling of Toolbar is done differently to the standard action bar, and is set directly onto the view.

   <android.support.v7.widget.Toolbar  
     xmlns:app="http://schemas.android.com/apk/res-auto"  
     android:id="@+id/my_awesome_toolbar"  
     android:layout_width="match_parent"  
     android:layout_height="wrap_content"  
     android:background="?attr/colorPrimary"  
     android:minHeight="?attr/actionBarSize"  
     app:theme="@style/ThemeOverlay.AppCompat.Light" />  

ThemeOverlay.AppCompat.Light : Changes the Toolbar title text color to Black.
ThemeOverlay.AppCompat.Dark.ActionBar : Changes the Toolbar title text color to White.


Usage of inflateMenu in Toolbar:

If you're using setSupportActionBar(toolbar); then inflateMenu of toolbar cannot be used, because Toolbar is acting like Actionbar. So, all the menu related callbacks are default.

The only time you need to call toolbar.inflateMenu() is when you are using the Toolbar as a standalone widget. In this case you need to manually populate the Toolbar with content/actions. For instance, if you want it to display actions, you need to inflate a menu into it:

 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) {  
      switch (item.getItemId()) {  
      case R.id.searchItem:  
           Toast.makeText(getApplicationContext(), "Search", Toast.LENGTH_SHORT).show();  
           break;  
      case R.id.filterItem:  
           Toast.makeText(getApplicationContext(), "Filter", Toast.LENGTH_SHORT).show();  
           break;  
      }  
      return true;  
      }  
 });  
 // Inflate a menu to be displayed in the toolbar  
 toolbar.inflateMenu(R.menu.toolbar_menu);  
 
res/xml/toolbar_menu.xml  
 <?xml version="1.0" encoding="utf-8"?>  
 <menu xmlns:android="http://schemas.android.com/apk/res/android"  
   xmlns:app="http://schemas.android.com/apk/res-auto" >  
   <item  
     android:id="@+id/searchItem"  
     android:icon="@android:drawable/ic_menu_search"  
     android:title="Search"  
     app:showAsAction="always"/>  
   <item  
     android:id="@+id/filterItem"  
     android:icon="@android:drawable/ic_menu_info_details"  
     android:title="Info"  
     app:showAsAction="always"/>  
 </menu>  


Navigations in Toolbar:

Here we can see how toolbar navigation works and this is similar to the action of setDisplayHomeAsUpEnabled(true) in the actionbar.
Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
toolbar.setTitle("Second Activity");
toolbar.setNavigationIcon(R.drawable.ic_up);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View view) {
           NavUtils.navigateUpTo(SecondActivity.this, IntentCompat.makeMainActivity(new ComponentName(SecondActivity.this, SecondActivity.class)));
           }
});


Customize Toolbar:

The customization of the toolbar here is to center align the title text and it is as follows.

<android.support.v7.widget.Toolbar  
     xmlns:app="http://schemas.android.com/apk/res-auto"  
     android:id="@+id/my_awesome_toolbar"  
     android:layout_width="match_parent"  
     android:layout_height="wrap_content"  
     android:background="?attr/colorPrimary"  
     android:minHeight="?attr/actionBarSize"  
     app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" >  
     <TextView  
       android:id="@+id/toolbar_title"  
       android:layout_width="wrap_content"  
       android:layout_height="wrap_content"  
       android:layout_gravity="center"  
       android:singleLine="true"  
       android:text="Toolbar Title"  
       android:textColor="@android:color/white"  
       android:textSize="18sp"  
       android:textStyle="bold" />  
</android.support.v7.widget.Toolbar>  


Source Code
You can download the source code by clicking here: ToolBarMaterialComp Source Code.  This project is built using eclipse IDE. Unzip and import the project into Eclipse, it’s a good idea to use the Project by clean and rebuild from the project menu. It works in all API levels above 2.3.

As always, thanks for reading :) 
Don't forget to +1 this blog and share this post on Google+ if you found it interesting!

Have something to add to this post? If you have any other quick thoughts/hints that you think people will find useful? Share it in the comments & feedback's are welcome.