3. Цели проекта
• Упростить интеграцию MVP паттерна;
• Избавиться от написания “рутинного” кода;
• Добавить дополнительный функционал.
4. Что такое MVP
View Presenter Model
● Представление (View) — реализует отображение данных, обращается к
представителю за обновлениями;
● Представитель (Presenter) — реализует взаимодействие между моделью
и представлением.
● Модель (Model) — содержит в себе бизнес-логику, получает данные из
хранилища.
8. Модуль mvp.
Имплементация. ViewState.
public class ViewState implements IViewState<ViewState.IViewStateView> {
public void save(@NotNull Bundle bundle)
public void restore(@NotNull Bundle bundle)
public void apply(@NotNull IViewStateView iViewStateView)
public interface IViewStateView {
//Methods to provide data from ViewState to View
}
}
9. Модуль mvp.
Имплементация. Presenter.
public class Presenter extends BaseAsyncPresenter<Presenter.IPresenterView> {
//BaseAsyncExecutorPresenter<Presenter.IPresenterView>
//BaseAsyncRxSchedulerPresenter<Presenter.IPresenterView>
//IAsyncPresenter<Presenter.IPresenterView>
//IPresenter<Presenter.IPresenterView>
public interface IPresenterView extends BaseAsyncPresenter.ITaskListener {
//Methods to provide data from View to Presenter and backwards.
}
}
11. Модуль mvp.
Имплементация. Presenter.
interface IAsyncPresenter<in T : IAsyncPresenter.ITaskListener> : IPresenter<T> {
fun cancel()
interface ITaskListener {
fun onTaskStatusChanged(taskId: Int, status: Int)
}
}
12. Модуль mvp.
Имплементация. Presenter.
open class BaseAsyncPresenter<T : IAsyncPresenter.ITaskListener> : BasePresenter<T>(),
IAsyncPresenter<T> {
fun <T> execute(callable: Callable<T>, executor: AbstractExecutorService, id: Int): Future<T>
fun execute(runnable: Runnable, executor: AbstractExecutorService, id: Int): Future<Unit>
13. Модуль mvp.
Имплементация. Presenter.
fun waitForViewIfNeeded(): T
protected fun checkIfInterruptedException(ex: Throwable?): Boolean
protected fun isInMainThread(): Boolean
protected inline fun postOnMainThread(crossinline body: () -> Unit)
14. Модуль mvp.
Имплементация. Presenter.
protected fun notifyTaskAdded(task: Int)
protected fun notifyTaskFinished(task: Int)
fun isTaskRunning(task: Int): Boolean
fun isAnyOfTasksRunning(vararg tasks: Int): Boolean
fun hasRunningTasks(): Boolean
15. Модуль mvp.
Имплементация. Presenter.
abstract class BaseAsyncExecutorPresenter<T : IAsyncPresenter.ITaskListener>
: BaseAsyncPresenter<T>(), IAsyncPresenter<T> {
protected abstract fun createExecutor(): ThreadPoolExecutor
fun <T> execute(callable: Callable<T>, id: Int): Future<T>
fun execute(runnable: Runnable, id: Int): Future<Unit>
protected fun useSaveThreadFactory(): Boolean = true
19. Модуль mvp.
Имплементация. Activity.
public class Activity extends BaseMvpActivity<IView, Presenter, ViewState> implements IView {
public IView getMvpView() { return this;}
public ViewState createViewState() { return new ViewState();}
public Presenter createPresenter() { return new Presenter();}
public void createView()
public void onInitialized(Presenter presenter, ViewState viewState)
public void onTaskStatusChanged(int taskId, int status)
}
20. Модуль mvp.
Имплементация. Fragment.
public class Fragment extends BaseMvpFragment<IView, Presenter, ViewState> implements IView {
public IView getMvpView() { return this;}
public ViewState createViewState() { return new ViewState();}
public Presenter createPresenter() { return new Presenter();}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
public void onInitialized(Presenter presenter, ViewState viewState)
public void onTaskStatusChanged(int taskId, int status)
}
21. Модуль mvp.
Сохранение компонентов.
public class Fragment extends BaseMvpFragment<IView, Presenter, ViewState> implements IView {
@Override
public boolean retainPresenter() {
return true;
}
@Override
public boolean retainViewState() {
return true;
}
}
22. Модуль mvp.
Вью инъекция и зануление.
@Layout(R.layout.fragment_layout)
public class Fragment extends BaseMvpFragment<IView, Presenter, ViewState> implements IView {
@InjectView(R.id.text_view)
protected TextView textView;
@Override
public boolean nullViews() {
return true;
}
}
24. Модуль mvp.
Подписка на жизненный цикл. Activity.
object ActivityLifecycle {
//Constants for supported activity lifecycle events
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@Inherited
annotation class OnLifecycleEvent(@ActivityEvent val event: Int)
}
25. Модуль mvp.
Подписка на жизненный цикл. Fragment.
object FragmentLifecycle {
//Constants for supported fragment lifecycle events
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@Inherited
annotation class OnLifecycleEvent(@FragmentEvent val event: Int)
}
26. Модуль mvp.
Подписка на жизненный цикл.
public class CameraManager {
@FragmentLifecycle.OnLifecycleEvent(event = FragmentLifecycle.ON_VIEW_CREATED)
public void onViewCreated()
@FragmentLifecycle.OnLifecycleEvent(event = FragmentLifecycle.ON_VIEW_CREATED)
public void onViewCreated(Fragment fragment)
@FragmentLifecycle.OnLifecycleEvent(event = FragmentLifecycle.ON_VIEW_CREATED)
public void onViewCreated(Fragment fragment, View view)
@FragmentLifecycle.OnLifecycleEvent(event = FragmentLifecycle.ON_VIEW_CREATED)
public void onViewCreated(Fragment fragment, View view, Bundle savedInstance)
}
27. Модуль mvp.
Подписка на жизненный цикл.
public class Fragment extends BaseMvpFragment<IView, Presenter, ViewState> implements IView {
private CameraManager cameraManager;
public Fragment() {
cameraManager = new CameraManager();
subscribe(cameraManager);
}
}
34. Модуль mvp_autosavable.
Сгенерированный класс.
public final class IViewWrap implements IView {
private final IView wrappedView;
private final Handler mainHandler = new Handler((Looper.getMainLooper()));
public IViewWrap(IView wrappedView) {
this.wrappedView = wrappedView;
}
38. Модуль mvp_view_wrap.
Использование.
public class Activity
extends BaseMvpActivity<IView, Presenter, ViewState>
implements IView {
private IViewWrap wrap = new IViewWrap(this);
@NotNull
@Override
public IView getMvpView() {
return wrap;
}
39. Модуль mvp_list.
Быстрая имплементация экранов со списком на основе
RecyclerView c
• Пейджингом
• Поиском
• Swipe to refresh
• Прогресс бары в списке и на весь экран
• Заглушки «нет контента» и «произошла ошибка»
42. Модуль mvp_list.
Имплементация. ViewState.
public class PagingViewState
extends BasePagingSearchableViewState<AwesomeEntity, PagingViewState.IViewStateView> {
public List<AwesomeEntity> getItems()
public void setItems(@Nullable List<AwesomeEntity> list)
public void save(@NotNull Bundle out)
public void restore(@NotNull Bundle inState)
public interface IViewStateView
extends BasePagingSearchableViewState.IViewStateView<AwesomeEntity>
}
43. Модуль mvp_list.
Имплементация. ViewState.
abstract class BasePagingSearchableViewState<I,
in V : BasePagingSearchableViewState.IViewStateView<I>> : IViewState<V> {
companion object {
@JvmField val NO_ERROR_CODE = -1
}
var query = ""
abstract var items: MutableList<I>?
var canLoadMore = false
var nextPageFailed = false
var errorCode = NO_ERROR_CODE
44. Модуль mvp_list.
Имплементация. ViewState.
interface IViewStateView<I> {
fun setQuery(query: String)
fun setItems(items: MutableList<I>, canLoadMore: Boolean, isSearch: Boolean)
fun setNextPageLoadFailed(code: Int)
fun setFirstPageLoadFailed(code: Int)
}
45. Модуль mvp_list.
Имплементация. Presenter.
public class PagingPresenter
extends BaseAsyncRxSchedulerPresenter<PagingPresenter.IPresenterView>
implements IPagingSearchablePresenter {
fun isFirstPageLoading(): Boolean
fun isNextPageLoading(): Boolean
fun cancelFirstPages()
fun cancelNextPages()
fun cancelAllPageRequests()
46. Модуль mvp_list.
Имплементация. Presenter.
public interface IPresenterView
extends IPagingSearchablePresenter.IPresenterView<AwesomeEntity,
PagingResponse<AwesomeEntity>> {
fun onFirstPageLoaded(response: PR)
fun onNextPageLoaded(response: PR)
fun onNextPageLoadFailed(code: Int)
fun onFirstPageLoadFailed(code: Int)
}
47. Модуль mvp_list.
Имплементация. Adapter.
public class PagingAdapter
extends BasePagingAdapter<AwesomeEntity, PagingAdapter.PagingAdapterListener> {
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
public interface PagingAdapterListener extends BasePagingAdapter.AdapterListener {
}
}
51. Модуль mvp_list.
Имплементация. Delegate.
public class PagingDelegate
extends BasePagingSearchableDelegate<AwesomeEntity,
PagingResponse<AwesomeEntity>,
IPagingView,
PagingPresenter,
PagingViewState>
implements IPagingView
52. Модуль mvp_list.
Имплементация. Delegate.
protected void loadFirstPage()
protected void loadNextPage()
public PagingAdapter createPagingAdapter(LayoutInflater inflater, List<AwesomeEntity> items)
public String getEmptyMessage(boolean isSearch)
public String getErrorMessage(boolean isSearch, int code)
53. Модуль mvp_list.
Имплементация. Delegate.
var searchView: SearchView? = null
var swipeRefreshLayout: SwipeRefreshLayout? = null
var recyclerView: RecyclerView? = null
var waitView: View? = null
open fun setErrorView(vError: View, tvErrorMessage: TextView, retryButton: View?)
open fun setEmptyView(vEmpty: View, tvEmptyMessage: TextView)