Революционный Android
ищем замену фрагментам
Олег Осипенко+
oleg.s.osipenko@gmail.com+
o.osipenko@rambler-co.ru
Революционный Android
Ищем замену фрагментам
Fragments API
• Android 3.0 Honeycomb
• 2011 год
• Адаптивный UI
• Backstack внутри Activity
• MVC
Революционный Android
Ищем замену фрагментам
Fragments API
Революционный Android
Ищем замену фрагментам
Революционный Android
Ищем замену фрагментам
Революционный Android
Ищем замену фрагментам
Fragments API
• сложный жизненный цикл (lolcycle)
• асинхронные транзакции
• конструирование фрагмента
• вложенные фрагменты
• архитектура?..
Революционный Android
Ищем замену фрагментам
Fragments API
что мы создаем при создании фрагмента?
<FrameLayout>
<ImageView />
<TextView />
</FrameLayout>
@Override
public View onCreateView (LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.some_view, container, null);
}
Революционный Android
Ищем замену фрагментам
Flow & Flow.Path
• Замена FragmentManager
• Механизм для создания 

и удаления отдельных View
• Журнал для истории переходов 

между экранами
Революционный Android
Ищем замену фрагментам
Flow & Flow.Path
Flow.set(Object newScreen);
Flow.goBack();
Переход к новому экрану
Возврат на предыдущий
Революционный Android
Ищем замену фрагментам
Flow & Flow.Path
public class SampleActivity implements Flow.Dispatcher {
5
@Override
public void dispatch(Traversal traversal,
TraversalCallback callback) {
Object newScreen = traversal.destination.top();
showNewScreen(newScreen);
callback.onTraversalCompleted();
}5
}
Революционный Android
Ищем замену фрагментам
Screen
public class AlbumListScreen extends Path
• объединяет View 

и соответствующий Presenter
Революционный Android
Ищем замену фрагментам
Mortar
• инструмент, использующий Dagger

для связывания View и Presenter
• Предоставляет каждому экрану

доступ к BundleService
Революционный Android
Ищем замену фрагментам
Mortar & Flow
@Layout(R.layout.album_list_screen)
@WithModule(AlbumListScreen.Module.class)
public class AlbumListScreen extends Path {}
Объявление экрана
Революционный Android
Ищем замену фрагментам
Mortar & Flow
public class AlbumListScreen extends Path {
5
@dagger.Module(injects = AlbumListView.class)
public static class Module {
5
@Provides List<Album> provideAlbums() {}
}
}
Объявление экрана
Революционный Android
Ищем замену фрагментам
Mortar & Flow
public class AlbumListScreen extends Path {
@Singleton
public static class Presenter extends

ViewPresenter<AlbumListView> {
5
@Override
public void onLoad(Bundle savedInstanceState) {
getView().showAlbums(albums);
}
}
}
Объявление экрана
Революционный Android
Ищем замену фрагментам
Mortar presenter
public abstract class Presenter {
void takeView(V view)
void dropView(V view)
boolean hasView()
V getView()
void onEnterScope()
void onLoad()
void onSave()
void onExitScope
}
Революционный Android
Ищем замену фрагментам
Mortar & Flow
Объявление экрана
<org.sample.SomeView>
<ImageView />
<TextView />
</org.sample.SomeView>
public class SomeView extends FrameLayout
Революционный Android
Ищем замену фрагментам
Mortar & Flow
Объявление экрана
public class AlbumListView extends ListView {
@Inject AlbumListScreen.Presenter presenter;
public AlbumListView(Context context, AttributeSet attr){
super(context, attr);
ObjectGraphService.inject(context, this);
}
}
Революционный Android
Ищем замену фрагментам
Mortar & Flow
Объявление экрана
public class AlbumListView extends ListView {
5
@Override protected void onAttachedToWindow() {
super.onAttachedToWindow();
presenter.takeView(this);
}
@Override protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
presenter.dropView(this);
}
}
Революционный Android
Ищем замену фрагментам
Mortar & Flow
Объявление экрана
public class AlbumListView extends ListView {
5
public void showAlbums(List<Album> albums) {
adapter.setAlbums(albums);
adapter.notifyDataSetChanged();
}
}
Революционный Android
Ищем замену фрагментам

Революционный Android. Ищем замену фрагментам