Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)Ontico
РИТ++ 2017, AppsConf
Зал Касабланка, 6 июня, 16:00
Тезисы:
http://appsconf.ru/2017/abstracts/2704.html
В последнее время паттерн MVP будоражит Android-комьюнити. Уже есть несколько довольно приличных библиотек, которые помогают использовать этот подход. Но с ними вам придётся писать много boilerplate-кода. Поэтому я хочу познакомить вас с Moxy. Покажу, как использовать её компоненты для решения задач, которые будут вставать перед вами, когда вы решите использовать паттерн MVP. И расскажу, как устроены эти компоненты, и почему именно так, чтобы вы не боялись использовать Moxy из-за потенциальных подводных камней.
Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)Ontico
РИТ++ 2017, AppsConf
Зал Касабланка, 6 июня, 16:00
Тезисы:
http://appsconf.ru/2017/abstracts/2704.html
В последнее время паттерн MVP будоражит Android-комьюнити. Уже есть несколько довольно приличных библиотек, которые помогают использовать этот подход. Но с ними вам придётся писать много boilerplate-кода. Поэтому я хочу познакомить вас с Moxy. Покажу, как использовать её компоненты для решения задач, которые будут вставать перед вами, когда вы решите использовать паттерн MVP. И расскажу, как устроены эти компоненты, и почему именно так, чтобы вы не боялись использовать Moxy из-за потенциальных подводных камней.
«Как я научился не волноваться и полюбил Android-MVP», Никита Бартишок, ABBYYMail.ru Group
Доклад о подходе к разработке Android-приложений с использованием MVP и Clean Architecture. Никита рассмотрит преимущества этого подхода перед традиционным, уделит отдельное внимание вопросам сохранения состояния в Android-MVP, а также особенностям взаимодействия между V и P.
Где кончается react native? / Павел Кондратенко (Rambler&Co)Ontico
РИТ++ 2017, Frontend Сonf
Зал Мумбаи, 5 июня, 11:00
Тезисы:
http://frontendconf.ru/2017/abstracts/2496.html
В своем выступлении я расскажу про то, как библиотека бумажных книг в нашей компании переехала в онлайн и причем тут react native. Погружаясь в архитектуру этой технологии я постараюсь дать представление о том, что можно выжать из нее и где заканчиваются ее возможности. Разберем потоки в приложении, возможные проблемы и все это на таких простых примерах как ActivityIndicator.
Если у вас еще не дошли руки до react native, но всегда хотели разобраться - приходите обязательно! Из моего доклада вы сможете, как минимум, получить представление об этой технологии.
Непомнящих Егор, Web-developer, ISS Art.
JS, Java, Iron Maiden. Практически вся моя жизнь связана так или иначе с IT — с 11 класса и до 5 курса я лидировал на олимпиадах, но погрузился в профессию уже на работе в ISS Art’е. Мною реализованы ряд интересных проектов — от мелких поделок на гитхабе, до крупных бизнес-порталов, системы мониторинга и прогнозирования состояния оборудования, векторного графического редактора для Flash-версии Google Maps, сложного плагина для SketchUp на Ruby и Unity-клиента для просмотра зданий под десктопными и мобильными платформами.
В общем, повидал всякие front-end’ы, не только Web. Буду рад поделиться опытом с коллегами по цеху. В докладе расскажу о том, как сократить объем кода вашего front-end'а на 7%.
Вопросы, возникающие при использовании MVC, и их решение при помощи VIPER.
1. Проблемы, решаемые VIPER-ом. История появления.
2. Структура VIPER-модуля
3. Сервисы
4. Data flow
5. Навигация
6. Вложенные модули
7. Data flow между модулями
8. Кодогенерация. Vipergen
«Как я научился не волноваться и полюбил Android-MVP», Никита Бартишок, ABBYYMail.ru Group
Доклад о подходе к разработке Android-приложений с использованием MVP и Clean Architecture. Никита рассмотрит преимущества этого подхода перед традиционным, уделит отдельное внимание вопросам сохранения состояния в Android-MVP, а также особенностям взаимодействия между V и P.
Где кончается react native? / Павел Кондратенко (Rambler&Co)Ontico
РИТ++ 2017, Frontend Сonf
Зал Мумбаи, 5 июня, 11:00
Тезисы:
http://frontendconf.ru/2017/abstracts/2496.html
В своем выступлении я расскажу про то, как библиотека бумажных книг в нашей компании переехала в онлайн и причем тут react native. Погружаясь в архитектуру этой технологии я постараюсь дать представление о том, что можно выжать из нее и где заканчиваются ее возможности. Разберем потоки в приложении, возможные проблемы и все это на таких простых примерах как ActivityIndicator.
Если у вас еще не дошли руки до react native, но всегда хотели разобраться - приходите обязательно! Из моего доклада вы сможете, как минимум, получить представление об этой технологии.
Непомнящих Егор, Web-developer, ISS Art.
JS, Java, Iron Maiden. Практически вся моя жизнь связана так или иначе с IT — с 11 класса и до 5 курса я лидировал на олимпиадах, но погрузился в профессию уже на работе в ISS Art’е. Мною реализованы ряд интересных проектов — от мелких поделок на гитхабе, до крупных бизнес-порталов, системы мониторинга и прогнозирования состояния оборудования, векторного графического редактора для Flash-версии Google Maps, сложного плагина для SketchUp на Ruby и Unity-клиента для просмотра зданий под десктопными и мобильными платформами.
В общем, повидал всякие front-end’ы, не только Web. Буду рад поделиться опытом с коллегами по цеху. В докладе расскажу о том, как сократить объем кода вашего front-end'а на 7%.
Вопросы, возникающие при использовании MVC, и их решение при помощи VIPER.
1. Проблемы, решаемые VIPER-ом. История появления.
2. Структура VIPER-модуля
3. Сервисы
4. Data flow
5. Навигация
6. Вложенные модули
7. Data flow между модулями
8. Кодогенерация. Vipergen
MVVM в WinForms – DevExpress Way (теория и практика)GoSharp
Из доклада вы узнаете о применении популярного паттерна MVVM для упрощения и ускорения процесса разработки desktop-приложений.
Будут рассмотрены общие проблемы этого паттерна и решения которые мы предлагаем в нашем кроссплатформенном MVVM фреймворке. Упор будет сделан на практические аспекты и техники в условиях использования платформы WinForms и контролов от DevExpress.
Разработка WPF приложений в стиле ViewModel FirstDenis Tsvettsih
Презентация к докладу «Разработка WPF приложений в стиле ViewModel First» с одиннадцатой конференции dotnetconf (Челябинск, 31 октября 2015)
http://dotnetconf.ru/materialy/viewmodelfirst
Мир мобильных телефонов очень сильно изменил нашу жизнь. В наше время невозможно представить современного человека, без этого чудо устройства. На рынке появляется все больше устройств и приложений. И чтобы удобнее пользоваться этими приложениями пользователи выбирают “умные” телефоны, или как их еще принято называть смартфоны. В своем докладе я хочу поделиться своим опытом автоматизации приложений под Android и iOS. Я расскажу о том, какие инструменты автоматизации я использовал. Поговорим о недостатках этих инструментов и какие из них стоит использовать у себя на проекте.
* Почему Angular 2 такой быстрый и как его ускорить еще сильнее?
* Как работает Change Detection механизм и как им управлять?
* Зачем нам Zone.js и Функциональное Реактивное Программирование?
* Как работать с Redux и Mobx в Angular 2 и что можно от этого выиграть?
Об этом и ряде других вещей вы узнаете из этого доклада.
Превышаем скоростные лимиты с Angular 2 / Алексей Охрименко (IPONWEB)Ontico
* Почему Angular 2 такой быстрый и как его ускорить еще сильнее?
* Как работает Change Detection механизм и как им управлять?
* Зачем нам Zone.js и Функциональное Реактивное Программирование?
* Как работать с Redux и Mobx в Angular 2 и что можно от этого выиграть?
Об этом и ряде других вещей вы узнаете из этого доклада.
Есть такая штука как инструментирование кода. Мало кто знает о ней, даже пользуясь результатами ее применения. Между тем, с инструментированием можно делать много всего интересного и, главное, полезного. Например, это может вам помочь лучше понять код или сделать процесс разработки более эффективным. Примеры инструментирования кода и принципы его работы.
DataArt Custom Software Engineering with a Human ApproachDataArt
DataArt is a global software engineering firm that takes a uniquely human approach to solving problems. With over 20 years of experience, teams of highly-trained engineers around the world, deep industry sector knowledge and ongoing technology research, we help clients create custom software that improves their operations and opens new markets. Powered by our People First principle, we work with clients at any scale and on any platform, and adapt alongside them as they evolve.
DataArt is a global software engineering firm that takes a uniquely human approach to solving problems. With over 20 years of experience, teams of highly-trained engineers around the world, deep industry sector knowledge, and ongoing technology research, we help clients create custom software that improves their operations and opens new markets. Powered by our People First principle, we work with clients at any scale and on any platform, and adapt alongside them as they evolve.
DataArt Financial Services and Capital MarketsDataArt
DataArt is a global software engineering firm that takes a uniquely human approach to solving problems. With over 20 years of experience, teams of highly-trained engineers around the world, deep industry sector knowledge, and ongoing technology research, we help clients create custom software that improves their operations and opens new markets. Powered by our People First principle, we work with clients at any scale and on any platform, and adapt alongside them as they evolve.
We integrate our engineering excellence with deeply human values that drive our business and our approach to relationships: curiosity, empathy, trust, honesty, and intuition. These qualities help us deliver high-value, high-quality solutions that our clients depend on, and lifetime partnerships they believe in.
DataArt has earned the trust of some of the world’s leading brands and most discerning clients, including Nasdaq, Travelport, Ocado, Centrica/Hive, Paddy Power Betfair, IWG, Univision, Meetup and Apple Leisure Group among others. DataArt brings together expertise of over 3000 professionals in 20 locations in the US, Europe, and Latin America.
Мы ежедневно посещаем десятки и сотни сайтов и периодически видим рекламу, зачастую даже не задумываясь, откуда она вообще берется. Почему именно эта реклама показана вам именно здесь? И какая роль JS во всем этом?
Рассмотрим:
• поговорим о жизненном цикле рекламного баннера и проследим его путь от рекламодателя до браузера;
• узнаем, кто же постоянно следит за нами в интернете, как много информации о нас им доступно;
• определим способы выявления некачественного трафика;
• разберемся, зачем нужно контролировать качество просмотров;
• обсудим, почему нельзя так просто взять и просмотреть всю статистику по рекламе в одном месте (или все-таки можно?).
Алексей Уманский, JS Developer, AnyMind Group. Опыт работы в IT – четыре года. Участвовал в тревел- и gamedev-проектах: разрабатывал крупный сервис по покупке авиабилетов, создавал систему игровых автоматов для онлайн казино. Последний год работал в Таиланде над продуктами в области Digital Marketing: онлайн биржа для influencer-ов и сервис по управлению рекламой на сайте, а так же сбору статистики по ней.
What's new in Android, Igor Malytsky ( Google Post I|O Tour)DataArt
This document summarizes new features and changes in Android development tools, Jetpack libraries, UI/UX, and more. It discusses expanded Kotlin and Jetpack support, new IDE features like navigation editor and resource manager, evolution of Architecture Components like ViewBinding, and new UI elements in Android like gesture navigation and bubbles. Google is also working on new tools for CameraX, benchmarking, and continued updates to Play Store, Machine Learning, and other platforms.
DevOps Workshop:Что бывает, когда DevOps приходит на проектDataArt
Александр Снеговой, DevOps Software Engineer в DataArt.
Более шести лет в IT. Сертифицированный AWS Solutions Architect Associate. Докладчик на международных научных конференциях. Религиозный фанат Docker.
Оксана Харчук, Senior QA Engineer.
Презентация:
Коммуникация в жизни QA. Как выстроить эффективные коммуникации тестировщику с бизнес аналитиком, разработчиком, менеджером и клиентом.
Нельзя просто так взять и договориться, или как мы работали со сложными людьмиDataArt
Эллина Азадова, QA Lead в DataArt Kherson.
Презентация:
Реальные примеры из своей практики, как работать со сложными людьми: интровертами, экстравертами, излишне эмоциональными и с постоянно пессимистически настроенными.
Дмитрий Клипинин, DevOps Engineer в GlobalLogic, более 10 лет опыта работы в IT, сертифицированный специалист Microsoft по технологиям Active Directory и SQL Server.
Презентация:
1. Эволюция системного администратора.
2. DevOps-практики.
3. Основные DevOps-инструменты.
Александр Снеговой, DevOps Software Engineer в DataArt Kherson. Более шести лет в IT. Сертифицированный AWS Solutions Architect Associate. Докладчик на международных научных конференциях. Религиозный фанат Docker.
Презентация:
1. Докеризация приложения.
2. Настройка CI/CD.
3. Развертывание инфраструктуры в AWS с помощью Terraform.
The document discusses Docker and Selenoid, with Docker being a tool to run applications in isolated containers and Selenoid being a tool for running Selenium tests in isolated Docker containers. Selenoid provides benefits over Selenium Grid like better resource usage, easier installation, and support for running each test in a separate container. The document also provides instructions for installing and running Selenoid using Docker or without Docker on different operating systems.
Volodymyr Zdvizhkov is a senior automation engineer who has experience with several UI testing frameworks including Selenium IDE, Selenium WebDriver, Selenium Grid, Selenide, and Selenoid. The document discusses the features of these frameworks and provides tips for writing effective automated tests such as using page object models and soft assertions. It emphasizes that Selenide allows writing concise, expressive, and stable UI tests in Java through its fluent API and automatic screenshot capturing on failures.
A. Sirota "Building an Automation Solution based on Appium"DataArt
This document provides an overview of building an automation solution using Appium. It discusses tools for mobile test automation, common pain points in testing, tips for running tests on real devices versus emulators, integrating mobile testing into a CI/CD pipeline, and using cloud services for testing. Examples are provided for testing a QR code scanning app and verifying call quality between two devices. Links to additional Appium documentation and cloud testing services are also included.
IT talk: Как я перестал бояться и полюбил TestNGDataArt
TestNG is a testing framework that provides features like parameterized tests, test factories, flexible parallel execution, and a rich extension model. The document discusses TestNG tips and tricks, common issues and workarounds, and the future of TestNG. It recommends using TestNG-Foundation to order listeners and run multiple annotation transformers. ExtendNG can help run before/after methods for specific groups. Test-Data-Supplier makes data providers more readable. While TestNG continues improving, JUnit 5 is an emerging rival testing framework.
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)