Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Tips and tricks du rebranding de l'app Captain ...
Search
Jeremie Martinez
December 12, 2016
Technology
1
330
Tips and tricks du rebranding de l'app Captain Train
Talk fait au PAUG le 12/12/16 en Français
Jeremie Martinez
December 12, 2016
Tweet
Share
More Decks by Jeremie Martinez
See All by Jeremie Martinez
Gradle, je t'aime, moi non plus…
jeremiemartinez
0
320
The evolution of Android notification
jeremiemartinez
5
4.8k
DevOps sur Android : from one git push to a Play Store release
jeremiemartinez
17
2.6k
See the Truth
jeremiemartinez
0
270
DevOps sur Android : D'un git push à une release Play Store
jeremiemartinez
5
570
Dagger 2 : Back to basics
jeremiemartinez
2
990
La stack réseau Android, disponible également pour vos backs
jeremiemartinez
0
470
Other Decks in Technology
See All in Technology
Why App Signing Matters for Your Android Apps - Android Bangkok Conference 2024
akexorcist
0
130
【Startup CTO of the Year 2024 / Audience Award】アセンド取締役CTO 丹羽健
niwatakeru
0
1.3k
Incident Response Practices: Waroom's Features and Future Challenges
rrreeeyyy
0
160
AWS Lambda のトラブルシュートをしていて思うこと
kazzpapa3
2
180
OCI Vault 概要
oracle4engineer
PRO
0
9.7k
飲食店データの分析事例とそれを支えるデータ基盤
kimujun
0
180
マルチプロダクトな開発組織で 「開発生産性」に向き合うために試みたこと / Improving Multi-Product Dev Productivity
sugamasao
1
310
Zennのパフォーマンスモニタリングでやっていること
ryosukeigarashi
0
160
生成AIが変えるデータ分析の全体像
ishikawa_satoru
0
170
iOS/Androidで同じUI体験をネ イティブで作成する際に気をつ けたい落とし穴
fumiyasac0921
1
110
AGIについてChatGPTに聞いてみた
blueb
0
130
Lambda10周年!Lambdaは何をもたらしたか
smt7174
2
110
Featured
See All Featured
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
38
1.8k
The World Runs on Bad Software
bkeepers
PRO
65
11k
BBQ
matthewcrist
85
9.3k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
131
33k
Building a Scalable Design System with Sketch
lauravandoore
459
33k
Code Review Best Practice
trishagee
64
17k
Optimising Largest Contentful Paint
csswizardry
33
2.9k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
27
840
Build The Right Thing And Hit Your Dates
maggiecrowley
33
2.4k
YesSQL, Process and Tooling at Scale
rocio
169
14k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
6
430
Art, The Web, and Tiny UX
lynnandtonic
297
20k
Transcript
@JeremMartinez From Captain Train… … to Trainline
None
Qu’est ce qu’une marque ?
Une icône 1
None
Des couleurs 2
Bonnes pratiques colors.xml Nommer vos couleurs selon le métier Garder
votre palette la plus petite possible Toujours faire des alias
<!-- 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>
<!-- 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>
<!-- 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>
Bonnes pratiques themes.xml Utiliser au maximum les thèmes Séparer vos
fichiers de thèmes : themes.xml styles.xml text_styles.xml
Theme
Theme Theme.CaptainTrain Theme.CaptainTrain.Exchange Theme.CaptainTrain.Cancellation
<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>
None
None
<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>
<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>
attrs.xml <resources> <attr name="ctColorTextAccent" format="reference|color" /> </resources>
<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
<?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
attrs.xml <resources> <attr name="ctButtonStyle" format="reference" /> </resources>
<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>
<Button android:id="@+id/btn_pay" style="?attr/ctButtonStyle" android:layout_width="match_parent" android:layout_height="wrap_content" tools:text="Pay €456.00"/>
Attrs ne fonctionnent pas dans les drawables *Valable pré-Lollipop
Puissant mais pas magique Compile-time vs runtime Rapidement bordélique API
très verrouillée
Des drawables 3
Garder vos raws !
None
Un nom 4
Des empty-states 5
None
None
Des animations 6
None
None
http://jeremie-martinez.com/2016/09/15/train-animations/
Des liens 7
Interne www.captaintrain.com
Interne www.trainline.eu
Interne www.trainline.fr
Interne www.trainline.de
Interne www.trainline.it
Interne www.trainline.es
Integration Deeplinks SmartLock For Password Facebook Sign in Sharing Google
Sign in App Indexing
Un package name 8
No!
None
Une timeline 9
2 semaines avant …
Sur le web
Dans les emails
Le jour J …
None
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>
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>
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>
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>
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>
ApplicationUpdatedReceiver public class ApplicationUpdatedReceiver extends BroadcastReceiver { …
} } @Override public void onReceive(Context context, Intent intent) {
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:
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();
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();
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();
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();
ApplicationUpdatedReceiver bumpToOneill(context); Notification Sauver un état pour l’écran …
Subir la rage 10
None
None
Conclusion Ça prend du temps Faire le minimum de changements
possible Vous allez oublier des choses Il y aura forcément des déçus
@JeremMartinez Questions ?