Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

of

Навигация в Android без боли и слез Slide 1 Навигация в Android без боли и слез Slide 2 Навигация в Android без боли и слез Slide 3 Навигация в Android без боли и слез Slide 4 Навигация в Android без боли и слез Slide 5 Навигация в Android без боли и слез Slide 6 Навигация в Android без боли и слез Slide 7 Навигация в Android без боли и слез Slide 8 Навигация в Android без боли и слез Slide 9 Навигация в Android без боли и слез Slide 10 Навигация в Android без боли и слез Slide 11 Навигация в Android без боли и слез Slide 12 Навигация в Android без боли и слез Slide 13 Навигация в Android без боли и слез Slide 14 Навигация в Android без боли и слез Slide 15 Навигация в Android без боли и слез Slide 16 Навигация в Android без боли и слез Slide 17 Навигация в Android без боли и слез Slide 18 Навигация в Android без боли и слез Slide 19 Навигация в Android без боли и слез Slide 20 Навигация в Android без боли и слез Slide 21 Навигация в Android без боли и слез Slide 22 Навигация в Android без боли и слез Slide 23 Навигация в Android без боли и слез Slide 24 Навигация в Android без боли и слез Slide 25 Навигация в Android без боли и слез Slide 26 Навигация в Android без боли и слез Slide 27 Навигация в Android без боли и слез Slide 28 Навигация в Android без боли и слез Slide 29 Навигация в Android без боли и слез Slide 30 Навигация в Android без боли и слез Slide 31 Навигация в Android без боли и слез Slide 32 Навигация в Android без боли и слез Slide 33 Навигация в Android без боли и слез Slide 34 Навигация в Android без боли и слез Slide 35 Навигация в Android без боли и слез Slide 36 Навигация в Android без боли и слез Slide 37 Навигация в Android без боли и слез Slide 38 Навигация в Android без боли и слез Slide 39 Навигация в Android без боли и слез Slide 40 Навигация в Android без боли и слез Slide 41 Навигация в Android без боли и слез Slide 42 Навигация в Android без боли и слез Slide 43 Навигация в Android без боли и слез Slide 44 Навигация в Android без боли и слез Slide 45 Навигация в Android без боли и слез Slide 46 Навигация в Android без боли и слез Slide 47 Навигация в Android без боли и слез Slide 48 Навигация в Android без боли и слез Slide 49 Навигация в Android без боли и слез Slide 50 Навигация в Android без боли и слез Slide 51 Навигация в Android без боли и слез Slide 52 Навигация в Android без боли и слез Slide 53 Навигация в Android без боли и слез Slide 54 Навигация в Android без боли и слез Slide 55 Навигация в Android без боли и слез Slide 56 Навигация в Android без боли и слез Slide 57 Навигация в Android без боли и слез Slide 58 Навигация в Android без боли и слез Slide 59 Навигация в Android без боли и слез Slide 60 Навигация в Android без боли и слез Slide 61 Навигация в Android без боли и слез Slide 62 Навигация в Android без боли и слез Slide 63 Навигация в Android без боли и слез Slide 64 Навигация в Android без боли и слез Slide 65 Навигация в Android без боли и слез Slide 66 Навигация в Android без боли и слез Slide 67 Навигация в Android без боли и слез Slide 68 Навигация в Android без боли и слез Slide 69 Навигация в Android без боли и слез Slide 70 Навигация в Android без боли и слез Slide 71 Навигация в Android без боли и слез Slide 72 Навигация в Android без боли и слез Slide 73
Upcoming SlideShare
Luonnostaan vahva klubin tuotekatalogi
Next
Download to read offline and view in fullscreen.

0 Likes

Share

Download to read offline

Навигация в Android без боли и слез

Download to read offline

Подробная статья по докладу: https://habrahabr.ru/company/mobileup/blog/314838/

Team Lead MobileUp Константин Цховребов выступил в Новосибирске на IT-конференций DevFest.

Поделиться азами гибкой простой и функциональной навигации по экранам при использовании MVP в Android. Рассказал, как сделать код навигации чистым и lifecycle-безопасным, а любую, даже самую навороченную цепочку переходов по экранам – делом пары строк.

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all
  • Be the first to like this

Навигация в Android без боли и слез

  1. 1. Навигация без боли и слез Константин Цховребов Android Team Leader
  2. 2. Первый большой проект на MVP
  3. 3. В теории все прекрасно! Первый большой проект на MVP
  4. 4. В теории все прекрасно! Первый большой проект на MVP На практике встречаешь ANDROID
  5. 5. Навигация в андроид приложении
  6. 6. Навигация в андроид приложении ●  Переход между экранами
  7. 7. Навигация в андроид приложении ●  Переход между экранами ●  Экраны сменяются в некотором контейнере
  8. 8. Навигация в андроид приложении ●  Переход между экранами ●  Экраны сменяются в некотором контейнере ●  Для совершения перехода нужен Context
  9. 9. А что если Fragment сделать презентером?
  10. 10. А что если Fragment сделать презентером? 1.  Lifecycle
  11. 11. А что если Fragment сделать презентером? 1.  Lifecycle 2.  Нужен универсальный подход (Activity/Fragment/View)
  12. 12. А что если Fragment сделать презентером? 1.  Lifecycle 2.  Нужен универсальный подход (Activity/Fragment/View) 3.  Context (и другие классы)
  13. 13. Mosby (http://hannesdorfmann.com/mosby/) public interface LoginView extends MvpView { public void showLoginForm(); public void showError(); public void showLoading(); public void loginSuccessful(); } public class LoginFragment … implements LoginView { … // Called when login was successful @Override public void loginSuccessful() { getActivity().finish(); } … }
  14. 14. Готовые решения Flow (https://github.com/square/flow) Conductor (https://github.com/bluelinelabs/Conductor)
  15. 15. Требования к идеальной навигации
  16. 16. Требования к идеальной навигации ●  прямой доступ из презентера
  17. 17. Требования к идеальной навигации ●  прямой доступ из презентера ●  не завязана на фрагменты
  18. 18. Требования к идеальной навигации ●  прямой доступ из презентера ●  не завязана на фрагменты ●  не фреймворк
  19. 19. Требования к идеальной навигации ●  прямой доступ из презентера ●  не завязана на фрагменты ●  не фреймворк ●  короткие вызовы
  20. 20. Требования к идеальной навигации ●  прямой доступ из презентера ●  не завязана на фрагменты ●  не фреймворк ●  короткие вызовы ●  легка в расширении
  21. 21. Требования к идеальной навигации ●  прямой доступ из презентера ●  не завязана на фрагменты ●  не фреймворк ●  короткие вызовы ●  легка в расширении ●  приспособлена для тестов
  22. 22. Требования к идеальной навигации ●  прямой доступ из презентера ●  не завязана на фрагменты ●  не фреймворк ●  короткие вызовы ●  легка в расширении ●  приспособлена для тестов ●  не зависит от жизненного цикла!
  23. 23. //TODO: ●  прямой доступ из презентера ●  не завязана на фрагменты ●  не фреймворк ●  короткие вызовы ●  легка в расширении ●  приспособлена для тестов ●  не зависит от жизненного цикла!
  24. 24. Это реальный проект!
  25. 25. Команды переходов
  26. 26. Команды переходов Forward(String screenKey, Object transitionData);
  27. 27. Команды переходов Forward(String screenKey, Object transitionData); Back();
  28. 28. Команды переходов Forward(String screenKey, Object transitionData); Back(); BackTo(String screenKey);
  29. 29. Команды переходов Forward(String screenKey, Object transitionData); Back(); BackTo(String screenKey); Replace(String screenKey, Object transitionData);
  30. 30. SystemMessage SystemMessage(String message);
  31. 31. Navigator public interface Navigator { void applyCommand(Command command); }
  32. 32. Navigator public interface Navigator { void applyCommand(Command command); } public class MainActivity extends Activity { private Navigator navigator = new Navigator() { @Override public void applyCommand(Command command) { ... } } }
  33. 33. //TODO: ●  прямой доступ из презентера ●  не завязана на фрагменты ●  не фреймворк ●  короткие вызовы ●  легка в расширении ●  приспособлена для тестов ●  не зависит от жизненного цикла!
  34. 34. //TODO: ●  прямой доступ из презентера ●  не завязана на фрагменты ●  не фреймворк ●  короткие вызовы ●  легка в расширении ●  приспособлена для тестов ●  не зависит от жизненного цикла! ✓
  35. 35. public class Presenter { @Inject Navigator navigator; private void next() { navigator.applyCommand(new Forward(“Some screen”)); } }
  36. 36. //TODO: ●  прямой доступ из презентера ●  не завязана на фрагменты ●  не фреймворк ●  короткие вызовы ●  легка в расширении ●  приспособлена для тестов ●  не зависит от жизненного цикла! ✓
  37. 37. //TODO: ●  прямой доступ из презентера ●  не завязана на фрагменты ●  не фреймворк ●  короткие вызовы ●  легка в расширении ●  приспособлена для тестов ●  не зависит от жизненного цикла! ✓ ✓
  38. 38. public class Presenter { @Inject Navigator navigator; private void authError() { navigator.applyCommand(new BackTo(null)); navigator.applyCommand(new Replace("Login screen", null)); navigator.applyCommand(new SystemMessage("Token expired!")); } }
  39. 39. Router public class Router extends BaseRouter { void newRootScreenWithMessage(String screenKey, Object data, String message) {...} }
  40. 40. Router public class Router extends BaseRouter { void newRootScreenWithMessage(String screenKey, Object data, String message) {...} } public class Presenter { @Inject Router router; private void authError() { router.newRootScreenWithMessage("Login screen", null, "Token expired!"); } }
  41. 41. //TODO: ●  прямой доступ из презентера ●  не завязана на фрагменты ●  не фреймворк ●  короткие вызовы ●  легка в расширении ●  приспособлена для тестов ●  не зависит от жизненного цикла! ✓ ✓
  42. 42. //TODO: ●  прямой доступ из презентера ●  не завязана на фрагменты ●  не фреймворк ●  короткие вызовы ●  легка в расширении ●  приспособлена для тестов ●  не зависит от жизненного цикла! ✓ ✓ ✓
  43. 43. public class Router extends BaseRouter { private Navigator navigator; public void setNavigator(Navigator navigator) { this.navigator = navigator; } public void removeNavigator() { this.navigator = null; } public void newRootScreenWithMessage(String screenKey, Object data, String message) { if (navigator != null) { navigator.applyCommand(new BackTo(null)); navigator.applyCommand(new Replace("Login screen", null)); navigator.applyCommand(new SystemMessage("Token expired!")); } } }
  44. 44. public class MainActivity extends Activity { @Override protected void onResume() { super.onResume(); router.setNavigator(navigator); } @Override protected void onPause() { super.onPause(); router.removeNavigator(); } }
  45. 45. Presenter View load()
  46. 46. ViewPresenter load() request()
  47. 47. Presenter request() View
  48. 48. Presenter request() response() View
  49. 49. Presenter Router request() response() View
  50. 50. Presenter RouterImpl Command Queue request() response() View
  51. 51. ViewPresenter RouterImpl Command Queue request() response()
  52. 52. //TODO: ●  прямой доступ из презентера ●  не завязана на фрагменты ●  не фреймворк ●  короткие вызовы ●  легка в расширении ●  приспособлена для тестов ●  не зависит от жизненного цикла! ✓ ✓ ✓
  53. 53. //TODO: ●  прямой доступ из презентера ●  не завязана на фрагменты ●  не фреймворк ●  короткие вызовы ●  легка в расширении ●  приспособлена для тестов ●  не зависит от жизненного цикла! ✓ ✓ ✓ ✓
  54. 54. Unit тестирование @Test public void someTest() throws Exception { Router mockRouter = mock(Router.class); Presenter presenter = new Presenter(); presenter.onNextButtonClicked(); verify(mockRouter, times(1)).navigateTo( eq("Some screen"), argument.capture() ); }
  55. 55. //TODO: ●  прямой доступ из презентера ●  не завязана на фрагменты ●  не фреймворк ●  короткие вызовы ●  легка в расширении ●  приспособлена для тестов ●  не зависит от жизненного цикла! ✓ ✓ ✓ ✓
  56. 56. //TODO: ●  прямой доступ из презентера ●  не завязана на фрагменты ●  не фреймворк ●  короткие вызовы ●  легка в расширении ●  приспособлена для тестов ●  не зависит от жизненного цикла! ✓ ✓ ✓ ✓ ✓
  57. 57. Расширение возможностей ●  в большинстве случаев достаточно добавить метод в Router и реализовать его с помощью Command ●  реже необходимо создать новую Command
  58. 58. //TODO: ●  прямой доступ из презентера ●  не завязана на фрагменты ●  не фреймворк ●  короткие вызовы ●  легка в расширении ●  приспособлена для тестов ●  не зависит от жизненного цикла! ✓ ✓ ✓ ✓ ✓
  59. 59. //TODO: ●  прямой доступ из презентера ●  не завязана на фрагменты ●  не фреймворк ●  короткие вызовы ●  легка в расширении ●  приспособлена для тестов ●  не зависит от жизненного цикла! ✓ ✓ ✓ ✓ ✓ ✓
  60. 60. //TODO: ●  прямой доступ из презентера ●  не завязана на фрагменты ●  не фреймворк ●  короткие вызовы ●  легка в расширении ●  приспособлена для тестов ●  не зависит от жизненного цикла! ✓ ✓ ✓ ✓ ✓ ✓ ✓
  61. 61. Cicerone Чичероне - (устар.) гид для иностранцев https://github.com/terrakok/Cicerone repositories { maven { url 'https://dl.bintray.com/terrakok/terramaven/' } } dependencies { //Cicerone compile 'ru.terrakok.cicerone:cicerone:1.0' }
  62. 62. Для кого мы ее создали?
  63. 63. Для кого мы ее создали? Для себя :)
  64. 64. Для кого мы ее создали? Почему она может пригодиться вам? Для себя :)
  65. 65. Для кого мы ее создали? ●  В приложении нелинейная навигация Почему она может пригодиться вам? Для себя :)
  66. 66. Для кого мы ее создали? ●  В приложении нелинейная навигация ●  Отделение логики от отображения Почему она может пригодиться вам? Для себя :)
  67. 67. Для кого мы ее создали? ●  В приложении нелинейная навигация ●  Отделение логики от отображения ●  Сохранение вызовов навигации после возвращения к приложению Почему она может пригодиться вам? Для себя :)
  68. 68. Возможности Cicerone public class Router extends BaseRouter { void navigateTo(String screenKey, Object data); void newScreenChain(String screenKey, Object data); void newRootScreen(String screenKey, Object data); void replaceScreen(String screenKey, Object data); void backTo(String screenKey); void exit(); void exitWithMessage(String message); void showSystemMessage(String message); } public abstract class FragmentNavigator implements Navigator {}
  69. 69. Спасибо за внимание! Вопросы? email: terrakok@mobileup.ru telegram: @terrakok https://github.com/terrakok/Cicerone

Подробная статья по докладу: https://habrahabr.ru/company/mobileup/blog/314838/ Team Lead MobileUp Константин Цховребов выступил в Новосибирске на IT-конференций DevFest. Поделиться азами гибкой простой и функциональной навигации по экранам при использовании MVP в Android. Рассказал, как сделать код навигации чистым и lifecycle-безопасным, а любую, даже самую навороченную цепочку переходов по экранам – делом пары строк.

Views

Total views

1,397

On Slideshare

0

From embeds

0

Number of embeds

1

Actions

Downloads

10

Shares

0

Comments

0

Likes

0

×