Migrer son ActionBar vers la ToolBar (Seconde Partie) : Mise en place de l'action mode

b2ap3_thumbnail_Android2ee-logo-BIG_blue-1024x375.png

Et bonjour tout le monde,

 Continuons notre découverte de la ToolBar et en particulier regardons comment mettre l'ActionMode en place. Si vous n'avez pas lu ce dernier article, il vous explique la mise en place de la ToolBar.

Tout d'abord qu'est-ce que l'ActionMode ? C'est la capacité de changer notre ToolBar pour n'afficher que des actions lors d'un évènement utilisateur particulier. L'exemple compréhensible est quand je sélectionne un mail, la ToolBar affiche de nouvelles actions.

C'est ce changement que l'on nomme l'ActionMode et grosso modo, cela correspond juste à demander à notre ToolBar d'afficher un nouveau fichier xml de Menu. Oui, en fait c'est trivial. Avant ça l'était vraiment, maintenant à deux trois petits détails, ça l'est toujours. Regardons comment le mettre en place:

 

ActionMode Off

ActionMode 

 ActionMode On

ActionModeOn

Le code Java ou la définition des menus n'a pas changé (non, toi non plus tout n'a pas changé - Julio Iglesias )

Fichiers Xml des menus

Comme vous l'avez compris, il nous faut deux menus xml pour mettre en place l'ActionMode. Le premier est l'OptionMenu naturel de votre activité (fragment) et le second celui que vous souhaitez afficher lorsque l'ActionMode est activé.

Il est évident que c'est vos menus, vous mettez les items que vous souhaitez afficher, mes fichiers sont des fichiers d'exemples :)=

 res\menu\main_menu.xml (Votre menu normal)

<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/action_settings"/>
</menu>

res\menu\action_mode.xml (Votre menu lorsque l'ActionMode est activé)

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:actionbarcompat_mse="http://schemas.android.com/apk/res-auto" >

<item
android:id="@+id/action_one"
android:icon="@drawable/ic_action_one"
android:orderInCategory="0"
actionbarcompat_mse:showAsAction="always"
android:title="One"/>
<item
android:id="@+id/action_two"
android:icon="@drawable/ic_action_two"
android:orderInCategory="1"
actionbarcompat_mse:showAsAction="always"
android:title="Two"/>
<item
android:id="@+id/action_one_duplicate"
android:icon="@drawable/ic_action_one"
android:orderInCategory="0"
actionbarcompat_mse:showAsAction="always"
android:title="One2"/>
<item
android:id="@+id/action_two_duplicate"
android:icon="@drawable/ic_action_two"
android:orderInCategory="0"
actionbarcompat_mse:showAsAction="ifRoom"
android:title="Two2"/>
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
actionbarcompat_mse:showAsAction="never"
android:title="@string/action_settings"/>

</menu>

 

 Comme vous le constatez, il n'y a aucun changement dans ces fichiers xml par rapport aux fichiers xml que nous utilisions poru l'ActionBarCompat.

Fichier du Layout

Comme expliqué dans l'article précédent, il faut que vous déclariez votre ToolBar dans le fichier de Layout de votre activité pour que celle ci apparraissent:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ActionModeActivity" >


<include layout="@layout/my_toolbar"/>


<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">

où le fichier res\layout\my_toolbar.xml est

<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toolbar"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v7.widget.Toolbar>

Code Java

Comme toujours avec la ToolBar, vous devez étendre l'AppCompatActivity et définir votre ToolBar comme étant l'ActionBar de votre activité:

public class ActionModeActivity extends AppCompatActivity {
/**
* The actionMode
*/
ActionMode mMode;
/**
* The action Bar
*/
private ActionBar actionBar;
/**
* The ToolBar
*/
private Toolbar toolbar;
/***
* The ActionMode callBack
*/
Callback actionModeCallBack;
/***
* Boolean to know which version is running
*/
private boolean postICS,postLollipop;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_action_mode);
//find the toolbar
toolbar = (Toolbar) findViewById(R.id.toolbar);
//customize the toolbar
toolbar.setNavigationIcon(R.drawable.ic_action_custom_up);
postICS =getResources().getBoolean(R.bool.postICS);
postLollipop =getResources().getBoolean(R.bool.postLollipop);
if(postLollipop){
toolbar.setElevation(15);
}
//define the toolbar as the ActionBar
setSupportActionBar(toolbar);
actionBar=getSupportActionBar();
//You could also hide the action Bar
//getSupportActionBar().hide();

// Show the Up button in the action bar.
actionBar.setDisplayUseLogoEnabled(false);
actionBar.setDisplayHomeAsUpEnabled(true);
setListeners();
//initialize the actionMode callback
initializeActionModeCallBack();
}

Ensuite il vous faut initialiser votre ActionModeCallBack qui est le callback  du cycle de vie de l'ActionMode:

private void initializeActionModeCallBack() {
actionModeCallBack=new android.support.v7.view.ActionMode.Callback() {
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}

@Override
public void onDestroyActionMode(ActionMode mode) {
}

@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
getMenuInflater().inflate(R.menu.action_mode, menu);
return true;
}

@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
Toast.makeText(ActionModeActivity.this, "Got click: " + item, Toast.LENGTH_SHORT).show();
mode.finish();
return true;
}
};
}

 Ce callback possède 4 méthodes:

  • La méthode onCreateActionMode qui permet de créer le menu de l'ActionMode. Il suffit ainsi d'inflater le fichier xml que l'on souhaite;
  • La méthode onPrepareActionMode qui nous permet de mettre à jour le menu avant que celui soit affiché;
  • La méthode onDestroyActionMode qui nous permet de faire le ménage si besoin est;
  • La méthode onActionItemClicked qui nous permet de savoir qu'un menu item du menu de l'ActionMode à été cliqué et lequel.

Il ne nous reste plus qu'à savoir activer ou désactiver ce mode:

Pour l'activation (remarquez que mMode est une variable de classe) :

mMode = startSupportActionMode(actionModeCallBack);

Pour la désactivation:

mMode.finish();

Et voilà, c'est tout, vous pouvez activer ou désactiver l'ActionMode quand bon vous semble maintenant.

Gestion du styles: les détails sont ici.

 Il fauit spécifiquement rajouter au style de la ToolBar les valeurs suivantes:

res\values\myStyles.xml

<!--The Theme for the Actvity that have actionMode-->
<style name="ActionModeAppTheme" parent="AppTheme">
<item name="windowActionModeOverlay">true</item>
<item name="actionModeBackground">@color/primary_dark</item>
</style>

 C'est à dire, je ne souhaite pas voir l'ActionMode usuel (parce que sinon il apparait au-dessus de votre ToolBar et c'est très laid), je souhaite avoir une couleur particulière de fond pour ma ToolBar quand l'ActionMode est activé et j'utilise le Theme.Light pour surcharger mon thème actuel. 

Où le style de la ToolBar ressemble à:

res\values\myStyles.xml

<style name="AppBlankTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Main theme colors -->
<!-- your app branding color for the app bar -->
<item name="colorPrimary">@color/primary</item>
<!-- darker variant for the status bar and contextual app bars -->
<item name="colorPrimaryDark">@color/primary_dark</item>
<!-- theme UI controls like checkboxes and text fields -->
<item name="colorAccent">@color/accent</item>
</style>
<!--Both themes below are those accepted to make the ToolBar works-->
<!-- Base application theme. -->
<style name="AppTheme" parent="AppBlankTheme">
<!-- Customize your theme here. -->
<!-- Base application theme. -->
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="spinnerDropDownItemStyle">@style/mydropdown</item>
</style>

Et l'appliquer à votre activité (dans votre Manifest)

manifest.xml

<activity
android:name=".sample.ActionModeActivity"
android:label="@string/title_activity_actionmode"
android:parentActivityName=".MainActivity"
android:theme="@style/ActionModeAppTheme" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.android2ee.formation.lollipop.toolbar.MainActivity" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.android2ee.formation.lollipop.toolbar.EXAMPLE" />
</intent-filter>
</activity>
 

Remarques concernant la Support library et l'ActionBarCompat

Si vous penser que vous pouvez encore utiliser l'ActionBarCompat, vous faîtes une erreur, il vous faut migrer.

Pourquoi ? Pour ça:

 compileSdkVersion 21
...
defaultConfig {
applicationId "com.android2ee.formation.librairies.actionbar.compat"
minSdkVersion 9
targetSdkVersion 21
...
}
dependencies {
compile 'com.android.support:appcompat-v7:20.0.0'
}

Si vous souhaitez que l'ActionBar  marche, il vous faut figer le compileSdk, le TargetSdk et la SupportLib à 21.

Mais si vous souhaitez que l'Overlay (votre contenu passe sous l'Action), que le SplitWhenNarrow ou que les ProgressBar marche encore, vous devez figer tout ce petit monde à 20.

Ce qui veut dire qu'en fait, vous devez migrer :)

Conclusion

Je finis ces blogs, concernant la ToolBar, comme toujours, en remerciant Chris Banes (@chrisbanes) car  c'est à lui que l'on doit cette simplification et surtout cette libération de l'ActionBar,

so Thanks a billion Mr Banes.

Le tutorial ?

Bien sûr, il est fourni, il est sur GitHub, ici : https://github.com/MathiasSeguy-Android2EE/ToolBar4Github (et si vous souhaitez lui ajouter des étoiles à ce projet, je suis à fond, cela me fera plaisir, je l'avoue).

Et n'hésitez pas à l'utiliser, ce billet couvre 20% du tutorial que je vous donne. D'autres viendront pour vous expliquer comment modifier la ToolBar, mettre l'ActionView, le SearchWidget, tout ça tout ça et bien plus encore (la TabNavigation avec la DesignLibrary par exemple:).

Les prochaines formations Android d’Android2EE 
Paris:
Et du 29 Juin au 3 Juillet 2015 à Paris, Formation complète.

Et pour le reste, je reviens en septembre, sur Paris, Toulouse, Lyon 

En septembre, je vais aussi ouvrir de nouvelles formations. En particulier la formation "Ultimate Android" avec Architecture, Librairie, Lollipop et M preview" sur 5 jours... ahaha, j'ai trop hâte :)

A bientôt.

Mathias Séguy
Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.

Fondateur Android2EE
Formation – Expertise – Consulting Android.
Ebooks pour apprendre la programmation sous Android.
AndroidEvolution

Suivez moi sur Twitter
Rejoignez mon réseau LinkedIn

 

Related Posts