Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Lithoを使ってみた

 Lithoを使ってみた

2017/05/09 shibuya.apk #14

ymnder

May 09, 2017
Tweet

More Decks by ymnder

Other Decks in Programming

Transcript

  1. Lithoͷڧ͍ͱ͜Ζ • RecyclerView • 1000ms / 60fps ≒ 16ms •

    όΠϯυɾଌఆɾϨΠΞ΢τ·ͰΛߦ͏ඞཁ • FacebookͷNewsFeedͷΑ͏ͳͨ͘͞ΜͷViewType͕ ૝ఆ͞ΕΔ৔߹ʹޮՌΛൃش͢Δ 7
  2. LithoͰॻ͍ͯΈͨ dependencies { //Litho compile 'com.facebook.litho:litho-core:0.2.0' //contains basic component compile

    'com.facebook.litho:litho-widget:0.2.0' //annotation processor compile 'com.facebook.litho:litho-annotations:0.2.0' annotationProcessor 'com.facebook.litho:litho-processor:0.2.0' //for Yoga. Yoga has dependencies for native compile 'com.facebook.soloader:soloader:0.2.0' //Stetho plugin debugCompile 'com.facebook.litho:litho-stetho:0.2.0' } 16
  3. LithoͰॻ͍ͯΈͨ public class SplashActivity extends AppCompatActivity { @Override protected void

    onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); //ContextͷαϒΫϥεͰϥΠϒϥϦ಺Ͱ࢖͏৘ใΛ؅ཧ͢Δ final ComponentContext c = new ComponentContext(this); setContentView( //ComponentΛmountͨ͠ViewGroupΛฦ͢ LithoView.create( this, SplashComponent.create(c).build())); } } 17
  4. ComponentΛॻ͍ͯΈͨ //ଞͷίϯϙʔωϯτΛ·ͱΊΔίϯϙʔωϯτ @LayoutSpec public class SplashComponentSpec { @OnCreateLayout static ComponentLayout

    onCreateLayout(ComponentContext c) { return Column.create(c) .child( Text.create(c) .text(“Hello Litho :)”) .textSizeSp(30f) .withLayout() .alignSelf(YogaAlign.CENTER) ).justifyContent(YogaJustify.CENTER) .build(); } } 18
  5. LithoͰॻ͍ͯΈͨ public class SplashActivity extends AppCompatActivity { @Override protected void

    onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); //ContextͷαϒΫϥεͰϥΠϒϥϦ಺Ͱ࢖͏৘ใΛ؅ཧ͢Δ final ComponentContext c = new ComponentContext(this); setContentView( //ComponentΛmountͨ͠ViewGroupΛฦ͢ LithoView.create( this, SplashComponent.create(c).build())); } } 21
  6. LithoͰॻ͍ͯΈͨ public class SplashActivity extends AppCompatActivity { @Override protected void

    onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); //ContextͷαϒΫϥεͰϥΠϒϥϦ಺Ͱ࢖͏৘ใΛ؅ཧ͢Δ final ComponentContext c = new ComponentContext(this); setContentView( //ComponentΛmountͨ͠ViewGroupΛฦ͢ LithoView.create( this, SplashComponent.create(c).build())); } } 22
  7. LithoͰॻ͍ͯΈͨ public class SplashActivity extends AppCompatActivity { @Override protected void

    onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); //ContextͷαϒΫϥεͰϥΠϒϥϦ಺Ͱ࢖͏৘ใΛ؅ཧ͢Δ final ComponentContext c = new ComponentContext(this); setContentView( //ComponentΛmountͨ͠ViewGroupΛฦ͢ LithoView.create( this, SplashComponent.create(c).build())); } } 23
  8. ComponentΛॻ͍ͯΈͨ //ଞͷίϯϙʔωϯτΛ·ͱΊΔίϯϙʔωϯτ @LayoutSpec public class SplashComponentSpec { @OnCreateLayout static ComponentLayout

    onCreateLayout(ComponentContext c) { return Column.create(c) .child( Text.create(c) .text(“Hello Litho :)”) .textSizeSp(30f) .withLayout() .alignSelf(YogaAlign.CENTER) ).justifyContent(YogaJustify.CENTER) .build(); } } 24
  9. ComponentΛॻ͍ͯΈͨ //ଞͷίϯϙʔωϯτΛ·ͱΊΔίϯϙʔωϯτ @LayoutSpec public class SplashComponentSpec { @OnCreateLayout static ComponentLayout

    onCreateLayout(ComponentContext c) { return Column.create(c) .child( Text.create(c) .text(“Hello Litho :)”) .textSizeSp(30f) .withLayout() .alignSelf(YogaAlign.CENTER) ).justifyContent(YogaJustify.CENTER) .build(); } } 25
  10. ComponentΛॻ͍ͯΈͨ //ଞͷίϯϙʔωϯτΛ·ͱΊΔίϯϙʔωϯτ @LayoutSpec public class SplashComponentSpec { @OnCreateLayout static ComponentLayout

    onCreateLayout(ComponentContext c) { return Column.create(c) .child( Text.create(c) .text(“Hello Litho :)”) .textSizeSp(30f) .withLayout() .alignSelf(YogaAlign.CENTER) ).justifyContent(YogaJustify.CENTER) .build(); } } 27
  11. ComponentΛॻ͍ͯΈͨ //ଞͷίϯϙʔωϯτΛ·ͱΊΔίϯϙʔωϯτ @LayoutSpec public class SplashComponentSpec { @OnCreateLayout static ComponentLayout

    onCreateLayout(ComponentContext c) { return Column.create(c) .child( Text.create(c) .text(“Hello Litho :)”) .textSizeSp(30f) .withLayout() .alignSelf(YogaAlign.CENTER) ).justifyContent(YogaJustify.CENTER) .build(); } } 28
  12. ComponentΛॻ͍ͯΈͨ //ଞͷίϯϙʔωϯτΛ·ͱΊΔίϯϙʔωϯτ @LayoutSpec public class SplashComponentSpec { @OnCreateLayout static ComponentLayout

    onCreateLayout(ComponentContext c) { return Column.create(c) .child( Text.create(c) .text(“Hello Litho :)”) .textSizeSp(30f) .withLayout() .alignSelf(YogaAlign.CENTER) ).justifyContent(YogaJustify.CENTER) .build(); } } 30
  13. ComponentΛॻ͍ͯΈͨ //ଞͷίϯϙʔωϯτΛ·ͱΊΔίϯϙʔωϯτ @LayoutSpec public class SplashComponentSpec { @OnCreateLayout static ComponentLayout

    onCreateLayout(ComponentContext c) { return Column.create(c) .child( Text.create(c) .text(“Hello Litho :)”) .textSizeSp(30f) .withLayout() .alignSelf(YogaAlign.CENTER) ).justifyContent(YogaJustify.CENTER) .build(); } } 31
  14. Recycler @OnCreateLayout static ComponentLayout onCreateLayout(final ComponentContext c) { final RecyclerBinder

    recyclerBinder = new RecyclerBinder(c, new LinearLayoutInfo(c, VERTICAL, false)); final RecyclerEventsController controller = new RecyclerEventsController(); //... return Recycler.create(c) .binder(recyclerBinder) .recyclerEventsController(controller) .refreshHandler(ListComponent.onPTRrefresh(c, recyclerBinder, controller)) .onScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); //... } }) .build(); } 33
  15. Recycler @OnCreateLayout static ComponentLayout onCreateLayout(final ComponentContext c) { final RecyclerBinder

    recyclerBinder = new RecyclerBinder(c, new LinearLayoutInfo(c, VERTICAL, false)); final RecyclerEventsController controller = new RecyclerEventsController(); //... return Recycler.create(c) .binder(recyclerBinder) .recyclerEventsController(controller) .refreshHandler(ListComponent.onPTRrefresh(c, recyclerBinder, controller)) .onScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); //... } }) .build(); } 34
  16. Recycler @OnCreateLayout static ComponentLayout onCreateLayout(final ComponentContext c) { final RecyclerBinder

    recyclerBinder = new RecyclerBinder(c, new LinearLayoutInfo(c, VERTICAL, false)); final RecyclerEventsController controller = new RecyclerEventsController(); //... return Recycler.create(c) .binder(recyclerBinder) .recyclerEventsController(controller) .refreshHandler(ListComponent.onPTRrefresh(c, recyclerBinder, controller)) .onScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); //... } }) .build(); } 36
  17. Recycler @OnCreateLayout static ComponentLayout onCreateLayout(final ComponentContext c) { final RecyclerBinder

    recyclerBinder = new RecyclerBinder(c, new LinearLayoutInfo(c, VERTICAL, false)); final RecyclerEventsController controller = new RecyclerEventsController(); //... return Recycler.create(c) .binder(recyclerBinder) .recyclerEventsController(controller) .refreshHandler(ListComponent.onPTRrefresh(c, recyclerBinder, controller)) .onScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); //... } }) .build(); } 37
  18. Recycler @OnCreateLayout static ComponentLayout onCreateLayout(final ComponentContext c) { final RecyclerBinder

    recyclerBinder = new RecyclerBinder(c, new LinearLayoutInfo(c, VERTICAL, false)); final RecyclerEventsController controller = new RecyclerEventsController(); //... return Recycler.create(c) .binder(recyclerBinder) .recyclerEventsController(controller) .refreshHandler(ListComponent.onPTRrefresh(c, recyclerBinder, controller)) .onScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); //... } }) .build(); } 39
  19. Recycler @OnCreateLayout static ComponentLayout onCreateLayout(final ComponentContext c) { final RecyclerBinder

    recyclerBinder = new RecyclerBinder(c, new LinearLayoutInfo(c, VERTICAL, false)); final RecyclerEventsController controller = new RecyclerEventsController(); //... return Recycler.create(c) .binder(recyclerBinder) .recyclerEventsController(controller) .refreshHandler(ListComponent.onPTRrefresh(c, recyclerBinder, controller)) .onScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); //... } }) .build(); } 40
  20. Event • EventΛड͚औΓ͍ͨComponentʹఆٛ͢Δ @OnEvent(PTRRefreshEvent.class) static void onPTRrefresh(final ComponentContext c, @Param

    final RecyclerBinder recyclerBinder, @Param final RecyclerEventsController controller){ //… controller.clearRefreshing(); } 41
  21. Stetho plugin • Stetho(v1.5.0)ͱ࿈ܞ • re-start / re-compileͤͣʹमਖ਼Ͱ͖Δ • ࣮ࡍʹඍमਖ਼ΛՃ͑ͳ͕Βಈ͖Λ͔֬ΊΒΕΔ

    • Yogaͱ΋༑ୡʹͳΕͦ͏ • AndroidStudioͷlayout inspectorͰ͸ϑϥοτͳView ʹͳ͍ͬͯΔ 42
  22. ࢖ͬͯΈͯͲ͏͔ͩͬͨ • ίʔυΛ௥͍ʹ͍͘ • ࣗಈੜ੒ޙͷΫϥεΛࢀর͢ΔͨΊɺfind usage͕΍Γʹ͍͘ • annotation processorނʹίϯύΠϧϑΣʔζʹ࣮ߦ͞ΕΔ •

    SpecʹΞϊςʔγϣϯΛ௥Ճͨ͠৔߹࠶Ϗϧυ͕ඞཁͰ͋Δ • δΣενϟʔ΍ΞχϝʔγϣϯΛ൐͏μΠφϛοΫͳUI͸ࠓͷͱ ͜Ζͳ͍ • ࠓޙ௥Ճ͞ΕΔΒ͍͠ • xmlͰͷैདྷͷϨΠΞ΢τΛ͢΂ͯ୅ସ͢Δ΋ͷͰ͸ͳ͍ • AndroidStudioͰPreview͢Δ͜ͱ͕Ͱ͖ͳ͍ 48
  23. ΋ͬͱௐ͍ࠪͨ͠ͱ͜Ζ • Asynchronous Layout • Immutability and thread safety •

    http://fblitho.com/docs/asynchronous-layout • UIεϨουʹ౉͢લʹlayoutͱmeasureΛߦ͍ͬͯΔ • ͲͷΑ͏ʹόοΫάϥ΢ϯυͰॲཧ͞ΕͯΔͷ͔ʁ 50
  24. ༨ஊɿ຤ඌͷSpecͱ͸ • ྫɿNameComponentSpec • ίϯϙʔωϯτͷ໊લ͸SpecͰऴΘΒͤΔ • annotation processorͰNameComponentʹͳΔ • javapoet࢖༻͍ͯ͠Δɻ຤ඌʹSpecΛ͚ͭΔɻ

    • ɾhttps://github.com/facebook/litho/blob/master/ litho-processor/src/main/java/com/facebook/litho/ specmodels/model/SpecModelValidation.java#L53 53
  25. ͦͷଞ • https://news.ycombinator.com/item?id=14142321 • https://www.reddit.com/r/androiddev/comments/ 68i0hg/ review_of_the_new_facebook_litho_framework_part_1/ • https://www.reddit.com/r/androiddev/comments/ 66g0ve/facebook_for_developers_litho_a_declarative/

    • https://www.reddit.com/r/androiddev/comments/ 6659bn/litho_a_declarative_ui_framework_for_android/ • https://www.reddit.com/r/androiddev/comments/ 6784bv/glide_imageloading_component_for_litho/ 56