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
1k
La stack réseau Android, disponible également pour vos backs
jeremiemartinez
0
470
Other Decks in Technology
See All in Technology
複雑性の高いオブジェクト編集に向き合う: プラガブルなReactフォーム設計
righttouch
PRO
0
120
ブラックフライデーで購入したPixel9で、Gemini Nanoを動かしてみた
marchin1989
1
540
マルチプロダクト開発の現場でAWS Security Hubを1年以上運用して得た教訓
muziyoshiz
3
2.4k
Microsoft Azure全冠になってみた ~アレを使い倒した者が試験を制す!?~/Obtained all Microsoft Azure certifications Those who use "that" to the full will win the exam! ?
yuj1osm
2
110
10個のフィルタをAXI4-Streamでつなげてみた
marsee101
0
170
事業貢献を考えるための技術改善の目標設計と改善実績 / Targeted design of technical improvements to consider business contribution and improvement performance
oomatomo
0
100
生成AIのガバナンスの全体像と現実解
fnifni
1
190
Fanstaの1年を大解剖! 一人SREはどこまでできるのか!?
syossan27
2
170
NilAway による静的解析で「10 億ドル」を節約する #kyotogo / Kyoto Go 56th
ytaka23
3
380
GitHub Copilot のテクニック集/GitHub Copilot Techniques
rayuron
37
15k
kargoの魅力について伝える
magisystem0408
0
210
AI時代のデータセンターネットワーク
lycorptech_jp
PRO
1
290
Featured
See All Featured
Statistics for Hackers
jakevdp
796
220k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.3k
Side Projects
sachag
452
42k
Optimising Largest Contentful Paint
csswizardry
33
3k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
232
17k
Building a Scalable Design System with Sketch
lauravandoore
460
33k
jQuery: Nuts, Bolts and Bling
dougneiner
61
7.5k
The Cult of Friendly URLs
andyhume
78
6.1k
The Language of Interfaces
destraynor
154
24k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
2
170
The Illustrated Children's Guide to Kubernetes
chrisshort
48
48k
Building an army of robots
kneath
302
44k
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 ?