LMFR Mobility team‘s journey to open source
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050543/Leroy_Merlin.svg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5122177/pasted-from-clipboard.png)
# ~ curl http://lmfr.io/florianpaillard
{
name: "Florian",
company: "Leroy Merlin France",
function: "Mobile lead developer",
beginDate: "2014"
team: "Mobility team / Colibri team",
lm-projects : {
pandroid : "open source mobile archetype",
lm-library : "lm fr archetype extension"
delivery : "open source delivery plugin",
colibri-apps: "store apps",
innovation: "htc vive, wear os prototyping ...",
...
},
other-projects : {
robolytics : "mobile analytics tag manager",
one-jitsu : "Jiu-jitsu practitioners network",
booth-app : "FatBooth, AgingBooth, ...",
...
},
links : {
twitter: "@paillard_f"
linkedin : "http://lmfr.io/florianpaillard",
robolytics : "https://robolytics.sertook.com",
perso : "http://sertook.com"
}
}
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5038048/IMG_8140.jpg)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5037854/Sans_titre.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5038171/COLIBRI_LOGO_TXTDOWN_2x.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5037844/Pandroid.2.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5037849/logo.png)
![](https://media1.giphy.com/media/O5xRqLYayT9lu/giphy.gif)
DISCLAIMER
Mobile
Team
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050989/crowd-of-users.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050995/artificial-intelligence.png)
Standard developement
Mobile developement
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5051037/1_WTmS6pN9c_YPy38V71z_Lg.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5051039/multiple-users-silhouette.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5051085/graduate-student-with-graduation-cap-toga-and-tie.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5051088/searcher.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5051089/batman.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5051090/superman.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5051093/superman-flying.png)
VS
Team diversity
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5051051/Batman-v-Superman-Final-Trailer-hq.jpg)
LM
FR
CONTEXT
Mobility Team
3 mobile developpers
2014
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050611/icon__1_.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050612/icon2.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050614/passportt.png)
3 - 5 apps
BAMBOO
WEB TEAM
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5058609/parallax_fixed3.381b400a_2.png)
Roadmap LM 2015
Gestion (backo mobile)
Vente (pyxis mobile)
Leroy Merlin France Apps (ios android)
Mobility Team
+ 30 mobile developpers
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5037913/t5986-800-800-80.jpg)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5037856/Sans_titre.png)
2018
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050611/icon__1_.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050612/icon2.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050613/icon3.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050614/passportt.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050638/appawinna.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050643/lmbrowser.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050644/booster.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050645/enji.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050647/prm.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050649/qbat.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050650/qboost.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050657/pandroid_ic_launcher.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050658/ic_launcher.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050659/ic_launcher.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050660/ic_launcher.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050663/ic_launcher.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050664/ic_launcher.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050665/ic_launcher.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050666/ic_launcher.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050667/ic_launcher.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050668/ic_launcher.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050669/ic_launcher.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050735/icone_inventaire_permanent.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050737/icone_alerteurstock.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050744/web_hi_res_512.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050666/ic_launcher.png)
+ 40 apps & backend
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5038171/COLIBRI_LOGO_TXTDOWN_2x.png)
AMGP
to sum up
growing team
differents skills
large roadmap
no shared architecture
1 app = 1 architecture
![](https://media3.giphy.com/media/V1NxC1YoNEHBe/giphy.gif)
![](https://media3.giphy.com/media/ktcUyw6mBlMVa/giphy.gif)
Mobile Archetype
Abstract libraries
Navigation pattern
LMFR tools (Passport, Scanner, ...)
Design
Shared architecture
![](https://media3.giphy.com/media/EatwJZRUIv41G/giphy.gif)
![](https://media2.giphy.com/media/ToMjGpBmDyMmBrMmbf2/giphy.gif)
FAT
PRISONER
![](https://media0.giphy.com/media/N6funLtVsHW0g/giphy.gif)
![](https://media3.giphy.com/media/EPcvhM28ER9XW/giphy.gif)
Solution
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5051451/web_hi_res_512.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050543/Leroy_Merlin.svg.png)
LM Library
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5051451/web_hi_res_512.png)
Open source
Easy configuration
Optional dependencies
Performance
Security
Documentation
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5051451/web_hi_res_512.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5050543/Leroy_Merlin.svg.png)
LM Library
Inner source
Colibri fonctionnalities
- sso
- scanner
- analytics
- preferences
- micro services - (talk Adrien Leroy)
UI Guidelines
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5058244/Capture_d_écran_2018-06-25_à_09.40.01.png)
OPEN SOURCE
Open source
- Collaborate with others
- Developer commitment
- Better visibility for recruiting developers
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5052633/github1.png)
MobileTribe
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5051547/Open_Source_Initiative_keyhole.svg.png)
PANDROID INSIDES
Basics
Dependencies Injection
- Dagger
- App base component
- Auto injection
Architecture
- Single responsibility principle
- Screen inter-dependencies
- MVP pathern
Basics
Event bus
@OnClick(R.id.event_send_to)
public void sendToSecondFragment() {
eventBusManager.send(
"My message",
"EventTag",
EventBusManager.DeliveryPolicy.AT_LEAST_ONE
);
}
@EventReceiver({"EventTag"}) //Generate provider with a tag to filter event
public void onReceiveMessage(@EventTag String tag, String msg) {
logWrapper.d(TAG, "message with tag '"+tag+"' received : " + msg);
}
Basics
LifecycleDelegate
public class IcepickLifecycleDelegate extends SimpleLifecycleDelegate<Object> {
@Override
public void onCreateView(Object target, View view, Bundle savedInstanceState) {
super.onCreateView(target, view, savedInstanceState);
Icepick.restoreInstanceState(target, savedInstanceState);
}
@Override
public void onSaveView(Object target, Bundle outState) {
if (viewExist)
Icepick.saveInstanceState(target, outState);
}
}
public class MyFragment extends PandroidFragment<FragmentOpener>{
@BindLifeCycleDelegate
IcepickLifecycleDelegate icepickDelegate;
//...
Basics
LifecycleDelegate
reviewManager.getReview("1", new NetActionDelegate<Review>(this) {
@Override
public void success(Review result) {}
@Override
public void onNetworkError(int statusCode, String errorMessage, String body, Exception e) {}
});
reviewService.getReview("1")
.rxEnqueue()
//bind observer on lifecycle thanks to RxPandroidFragment
.compose(this.<Review>bindLifecycle())
.subscribe(
//...
);
Optional libraries
Gradle dsl
pandroid{
library('mylib') {
libParam1 'param1'
libParam2 'param2'
}
}
Auto implement & bind to lifecycle
Optional libraries
GoogleAnalytics
FirebaseAnalytics
RxJava
Retrofit
Glide
Icepick
Crashlytics
Butterknife
SuperToasts
...
Navigation - Opener
//To handle the event
receivers.add(new FragmentEventReceiver()
.setContainerId(R.id.main_content_container)
.setAnim(FragmentEventReceiver.ANIM_MATERIAL)
.addFragment(MaterialFragment.class)
.setBackStackTag("material"));
public class MaterialFragment extends PandroidFragment<MaterialOpener> implements OnBackListener {
@Override
public void onResume(ResumeState state) {
super.onResume(state);
switch (state) {
case FIRST_START:
materialTransitionLayout.addAnimationWithViewId(opener.ivInfos, R.id.material_iv);
materialTransitionLayout.addAnimationWithViewTag(opener.tvInfos, "coucou");
break;
//...
}
}
sendEvent(new MaterialOpener(ivInfos, tvInfos));
Kotlin dsl
adapter<String> {
holder {
layout = R.layout.cell_list
itemType = 0 //your can use class has type, hashcode will be used
binder = { view, data, index -> (view as Button).text = data }
}
holder {
layout = R.layout.cell_list
itemType = 1
holderClass = CustomTxtHolder::class
}
holder {
itemType = 2
factory = CustomHolderFactory()
}
itemTypes { adapter: PandroidAdapter<String>, item: String, position: Int -> position % 3 }
}
Logger
Presenter
Templates
Security
Async
Animation
Storage
And more
Lifecycle
LiveData
ViewModel
Navigation
Good tools ?
DELIVERY
Make your continuous delivery faster and easier
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5037849/logo.png)
-
powerful workflow
-
simply build and sign artifacts
-
archive all you need into space
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5056666/releaseGitFlow.gif)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/896861/images/5056687/106598324PandawaveNEWS-xlarge_trans_NvBQzQNjv4Bqeo_i_u9APj8RuoebjoAHt0k9u7HhRJvuo-ZLenGRumA.jpg)
THANK YOU
LMFR Mobility team‘s journey to open source - Decathlon Version
By Florian Paillard
LMFR Mobility team‘s journey to open source - Decathlon Version
With all the great resources and libraries available, building a new mobile app is easier than it’s ever been! However, when it comes to maintain a large number of applications in a growing team with differents skills and practices, it becomes more and more challenging every day. To resolve this and to go faster, Leroy Merlin decided to create tools. This talk will give you an insight into the process of creation of our open source projects : Pandroid Library and the Delivery Plugin.
- 383