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
350
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
340
The evolution of Android notification
jeremiemartinez
5
5k
DevOps sur Android : from one git push to a Play Store release
jeremiemartinez
17
2.7k
See the Truth
jeremiemartinez
0
310
DevOps sur Android : D'un git push à une release Play Store
jeremiemartinez
5
590
Dagger 2 : Back to basics
jeremiemartinez
2
1.1k
La stack réseau Android, disponible également pour vos backs
jeremiemartinez
0
510
Other Decks in Technology
See All in Technology
薬屋のひとりごとにみるトラブルシューティング
tomokusaba
0
380
はじめての転職講座/The Guide of First Career Change
kwappa
5
4.3k
Oracle Exadata Database Service on Cloud@Customer X11M (ExaDB-C@C) サービス概要
oracle4engineer
PRO
2
6.4k
Google Agentspaceを実際に導入した効果と今後の展望
mixi_engineers
PRO
3
760
プロジェクトマネジメントは不確実性との対話だ
hisashiwatanabe
0
110
o11yツールを乗り換えた話
tak0x00
2
1.6k
React Server ComponentsでAPI不要の開発体験
polidog
PRO
0
330
ファッションコーディネートアプリ「WEAR」における、Vertex AI Vector Searchを利用したレコメンド機能の開発・運用で得られたノウハウの紹介
zozotech
PRO
0
570
開発 × 生成AI × コミュニケーション:GENDAの開発現場で感じたコミュニケーションの変化 / GENDA Tech Talk #1
genda
0
290
「Roblox」の開発環境とその効率化 ~DAU9700万人超の巨大プラットフォームの開発 事始め~
keitatanji
0
140
AIのグローバルトレンド 2025 / ai global trend 2025
kyonmm
PRO
1
160
Backlog AI アシスタントが切り開く未来
vvatanabe
1
160
Featured
See All Featured
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
3k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
358
30k
Thoughts on Productivity
jonyablonski
69
4.8k
Code Reviewing Like a Champion
maltzj
525
40k
The Cult of Friendly URLs
andyhume
79
6.5k
BBQ
matthewcrist
89
9.8k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
7
810
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
44
2.4k
Designing for Performance
lara
610
69k
Adopting Sorbet at Scale
ufuk
77
9.5k
Navigating Team Friction
lara
188
15k
Faster Mobile Websites
deanohume
309
31k
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 ?