Tips and tricks du rebranding de l'app Captain Train

Tips and tricks du rebranding de l'app Captain Train

Talk fait au PAUG le 12/12/16 en Français

05dd369062f7c4e450e1e08d1471da5b?s=128

Jeremie Martinez

December 12, 2016
Tweet

Transcript

  1. @JeremMartinez From 
 Captain Train… … to Trainline

  2. None
  3. Qu’est ce qu’une marque ?

  4. Une icône 1

  5. None
  6. Des couleurs 2

  7. Bonnes pratiques colors.xml Nommer vos couleurs selon le métier Garder

    votre palette la plus petite possible Toujours faire des alias
  8. <!-- Official colors -->
 <color name="accent">#01c3a7</color>
 <color name="primary">#21314d</color>
 <color name="primaryDark">#1a273d</color>


    
 <!-- Text variants -->
 <color name="ct_text_primary">#323e42</color>
 <color name="ct_text_secondary">#8c9da1</color>
 <color name="ct_text_accent">#14b69f</color>
 
 <!-- Status colors -->
 <color name="ct_error">#e02007</color>
 <color name="ct_info">#0375b6</color>
 <color name="ct_success">#90c25b</color>
 <color name="ct_warning">#e87619</color>
  9. <!-- Official colors -->
 <color name="accent">#01c3a7</color>
 <color name="primary">#21314d</color>
 <color name="primaryDark">#1a273d</color>


    
 <!-- Text variants -->
 <color name="ct_text_primary">#323e42</color>
 <color name="ct_text_secondary">#8c9da1</color>
 <color name="ct_text_accent">#14b69f</color>
 
 <!-- Status colors -->
 <color name="ct_error">#e02007</color>
 <color name="ct_info">#0375b6</color>
 <color name="ct_success">#90c25b</color>
 <color name="ct_warning">#e87619</color>
  10. <!-- Official colors -->
 <color name="accent">#01c3a7</color>
 <color name="primary">#21314d</color>
 <color name="primaryDark">#1a273d</color>


    
 <!-- Text variants -->
 <color name="ct_text_primary">#323e42</color>
 <color name="ct_text_secondary">#8c9da1</color>
 <color name="ct_text_accent">#14b69f</color>
 
 <!-- Status colors -->
 <color name="ct_error">#e02007</color>
 <color name="ct_info">#0375b6</color>
 <color name="ct_success">#90c25b</color>
 <color name="ct_warning">#e87619</color>
  11. Bonnes pratiques themes.xml Utiliser au maximum les thèmes Séparer vos

    fichiers de thèmes : themes.xml styles.xml text_styles.xml
  12. Theme

  13. Theme Theme.CaptainTrain Theme.CaptainTrain.Exchange Theme.CaptainTrain.Cancellation

  14. <style name="Theme.CaptainTrain" parent="Base.Theme.CaptainTrain">
 <item name="colorAccent">@color/accent</item>
 </style> 
 
 <style name="Theme.CaptainTrain.Cancellation">


    <item name="colorAccent">@color/cancellation</item>
 </style> 
 
 <style name="Theme.CaptainTrain.Exchange">
 <item name="colorAccent">@color/exchange</item>
 </style>
  15. None
  16. None
  17. <style name="Base.Theme.CaptainTrain">
 <item name="colorControlNormal">?attr/colorAccent</item>
 </style>
 <style name="Theme.CaptainTrain">
 <item name="colorAccent">@color/accent</item>
 </style>

    
 <style name="Theme.CaptainTrain.Exchange">
 <item name="colorAccent">@color/exchange</item>
 </style>
  18. <style name="Base.Theme.CaptainTrain">
 <item name="colorControlNormal">?attr/colorAccent</item>
 </style>
 <style name="Theme.CaptainTrain">
 <item name="colorAccent">@color/accent</item>
 </style>

    <style name="Theme.CaptainTrain.Exchange">
 <item name="colorAccent">@color/exchange</item>
 </style>
  19. attrs.xml <resources>
 
 <attr name="ctColorTextAccent" format="reference|color" />
 
 </resources>

  20. <style name="Theme.CaptainTrain" parent="Base.Theme.CaptainTrain">
 <item name="colorAccent">@color/accent</item>
 <item name="ctColorTextAccent">@color/text_accent</item>
 </style>
 
 <style

    name="Theme.CaptainTrain.Cancellation">
 <item name="colorAccent">@color/cancellation</item>
 <item name="ctColorTextAccent">@color/text_cancellation</item>
 </style>
 
 <style name="Theme.CaptainTrain.Exchange">
 <item name="colorAccent">@color/exchange</item>
 <item name="ctColorTextAccent">@color/text_exchange</item>
 </style> themes.xml
  21. <?xml version="1.0" encoding="utf-8"?>
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
 
 <item
 android:color="@color/disabled"
 android:state_enabled="false" />


    
 <item
 android:color="?attr/ctColorTextAccent" />
 
 </selector>
 text_accent.xml
  22. attrs.xml <resources>
 
 <attr name="ctButtonStyle" format="reference" />
 
 </resources>

  23. <style name="Theme.CaptainTrain" parent="Base.Theme.CaptainTrain">
 <item name="colorAccent">@color/accent</item>
 <item name="ctColorTextAccent">@color/text_accent</item> <item name="ctButtonStyle">@style/Button.Action</item>
 </style>


    
 <style name="Theme.CaptainTrain.Cancellation">
 <item name="colorAccent">@color/cancellation</item>
 <item name="ctColorTextAccent">@color/text_cancellation</item> <item name="ctButtonStyle">@style/Button.Action.Cancellation</item>
 </style>
 
 <style name="Theme.CaptainTrain.Exchange">
 <item name="colorAccent">@color/exchange</item>
 <item name="ctColorTextAccent">@color/text_exchange</item> <item name="ctButtonStyle">@style/Button.Action.Exchange</item>
 </style>
  24. <Button
 android:id="@+id/btn_pay"
 style="?attr/ctButtonStyle"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 tools:text="Pay €456.00"/>

  25. Attrs ne fonctionnent pas dans les drawables *Valable pré-Lollipop

  26. Puissant mais pas magique Compile-time vs runtime Rapidement bordélique API

    très verrouillée
  27. Des drawables 3

  28. Garder vos raws !

  29. None
  30. Un nom 4

  31. Des empty-states 5

  32. None
  33. None
  34. Des animations 6

  35. None
  36. None
  37. http://jeremie-martinez.com/2016/09/15/train-animations/

  38. Des liens 7

  39. Interne www.captaintrain.com

  40. Interne www.trainline.eu

  41. Interne www.trainline.fr

  42. Interne www.trainline.de

  43. Interne www.trainline.it

  44. Interne www.trainline.es

  45. Integration Deeplinks SmartLock For Password Facebook Sign in Sharing Google

    Sign in App Indexing
  46. Un package name 8

  47. No!

  48. None
  49. Une timeline 9

  50. 2 semaines avant …

  51. Sur le web

  52. Dans les emails

  53. Le jour J …

  54. None
  55. AndroidManifest.xml <receiver
 android:enabled="true"
 android:exported="true"
 android:name="com.example.ApplicationUpdatedReceiver">
 <intent-filter>
 <action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
 </intent-filter>


    </receiver>
  56. AndroidManifest.xml <receiver
 android:enabled="true"
 android:exported="true"
 android:name="com.example.ApplicationUpdatedReceiver">
 <intent-filter>
 <action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
 </intent-filter>


    </receiver>
  57. AndroidManifest.xml <receiver
 android:enabled="true"
 android:exported="true"
 android:name="com.example.ApplicationUpdatedReceiver">
 <intent-filter>
 <action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
 </intent-filter>


    </receiver>
  58. AndroidManifest.xml <receiver
 android:enabled="true"
 android:exported="true"
 android:name="com.example.ApplicationUpdatedReceiver">
 <intent-filter>
 <action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
 </intent-filter>


    </receiver>
  59. AndroidManifest.xml <receiver
 android:enabled="true"
 android:exported="true"
 android:name="com.example.ApplicationUpdatedReceiver">
 <intent-filter>
 <action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
 </intent-filter>


    </receiver>
  60. ApplicationUpdatedReceiver public class ApplicationUpdatedReceiver extends BroadcastReceiver {
 
 
 …

    } }
 @Override
 public void onReceive(Context context, Intent intent) {
  61. ApplicationUpdatedReceiver String action = intent.getAction();
 if (TextUtils.isEmpty(action)) {
 return;
 }

    switch (action) {
 … break; } }
 @Override
 public void onReceive(Context context, Intent intent) { case Intent.ACTION_MY_PACKAGE_REPLACED:
  62. ApplicationUpdatedReceiver case Intent.ACTION_MY_PACKAGE_REPLACED: AppPreferences preferences = AppPreferences.from(context);
 int version =

    preferences. getInt(PREVIOUS_APP_VERSION, VERSION_CODES.NARIM); 
 if (version < VERSION_CODES.ONEILL) {
 bumpToOneill(context);
 version = VERSION_CODES.ONEILL;
 } 
 if (version < VERSION_CODES.PENDERGAST) {
 bumpToPendergast(context);
 version = VERSION_CODES.PENDERGAST;
 }
 
 preferences.edit().
 putInt(PREVIOUS_APP_VERSION, version).
 apply();
  63. ApplicationUpdatedReceiver case Intent.ACTION_MY_PACKAGE_REPLACED: AppPreferences preferences = AppPreferences.from(context);
 int version =

    preferences. getInt(PREVIOUS_APP_VERSION, VERSION_CODES.NARIM); 
 if (version < VERSION_CODES.ONEILL) {
 bumpToOneill(context);
 version = VERSION_CODES.ONEILL;
 } 
 if (version < VERSION_CODES.PENDERGAST) {
 bumpToPendergast(context);
 version = VERSION_CODES.PENDERGAST;
 }
 
 preferences.edit().
 putInt(PREVIOUS_APP_VERSION, version).
 apply();
  64. ApplicationUpdatedReceiver case Intent.ACTION_MY_PACKAGE_REPLACED: AppPreferences preferences = AppPreferences.from(context);
 int version =

    preferences. getInt(PREVIOUS_APP_VERSION, VERSION_CODES.NARIM); 
 if (version < VERSION_CODES.ONEILL) {
 bumpToOneill(context);
 version = VERSION_CODES.ONEILL;
 } 
 if (version < VERSION_CODES.PENDERGAST) {
 bumpToPendergast(context);
 version = VERSION_CODES.PENDERGAST;
 }
 
 preferences.edit().
 putInt(PREVIOUS_APP_VERSION, version).
 apply();
  65. ApplicationUpdatedReceiver case Intent.ACTION_MY_PACKAGE_REPLACED: AppPreferences preferences = AppPreferences.from(context);
 int version =

    preferences. getInt(PREVIOUS_APP_VERSION, VERSION_CODES.NARIM); 
 if (version < VERSION_CODES.ONEILL) {
 bumpToOneill(context);
 version = VERSION_CODES.ONEILL;
 } 
 if (version < VERSION_CODES.PENDERGAST) {
 bumpToPendergast(context);
 version = VERSION_CODES.PENDERGAST;
 }
 
 preferences.edit().
 putInt(PREVIOUS_APP_VERSION, version).
 apply();
  66. ApplicationUpdatedReceiver bumpToOneill(context); Notification Sauver un état pour l’écran …

  67. Subir la rage 10

  68. None
  69. None
  70. Conclusion Ça prend du temps Faire le minimum de changements

    possible Vous allez oublier des choses Il y aura forcément des déçus
  71. @JeremMartinez Questions ?