Created
September 21, 2019 10:40
-
-
Save zibellon/a69d75665454e76f74b8d678cf089517 to your computer and use it in GitHub Desktop.
Собственный координатор для управления экранами
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class CoordinatorMain { | |
public interface CustomBackBtnClicker { | |
void backClick(); | |
} | |
//Класс который отвечает за навигацию в приложении | |
private String LOG = "CoordinatorMAIN!"; | |
private Activity rootActivity; | |
//Несколько контрольных переменных | |
private Boolean KEYBOARD_VISIBLE = false; //Видна клавиатура или нет - ГЛОБАЛЬНО | |
private Boolean IS_TAB_SWITCHED = false; //Используется для показа - СМЕНИЛИ МЫ ВКЛАДКУ ИЛИ НЕТ - ДЛЯ КОРНЕВЫХ ЭКРАНОВ, ПРОБЛЕМА С КНОПКОЙ НАЗАД | |
private Boolean customBackBtn = false; //Переменная которая показывает нужно обработать кнопку назад как всегда или для нее есть свой метод обработки | |
private CustomBackBtnClicker customBackBtnClicker; //Кастомная кнопка назад - еси ее надо как то по особенному обработать в активити или фрагменте | |
private List<RouterTransaction> routerTransactionList; | |
private ViewGroup fullScreenContainer; | |
private ViewGroup botNavContainer; | |
private Router navRouter; | |
private Integer curSwitchIndex = 0; | |
private Boolean needToPopRoot = false; | |
private Router currentRouter; //Текущий роутер для детей() | |
private Router mainRouter; //Главный роутер(Для большого экрана) | |
private AHBottomNavigation ahBottomNavigation; //Боттом навигатион! | |
private static CoordinatorMain coordinatorMain; | |
//Инициализация координатора | |
public static void init() { | |
coordinatorMain = new CoordinatorMain(); | |
} | |
//Получение координатора | |
public static CoordinatorMain getInstance() { | |
return coordinatorMain; | |
} | |
//Установка корневого активити - для кнопки назад | |
public void setRootActivity(@NonNull Activity rootActivity) { | |
this.rootActivity = rootActivity; | |
KeyboardVisibilityEvent.setEventListener(this.rootActivity, new KeyboardVisibilityEventListener() { | |
@Override | |
public void onVisibilityChanged(boolean isOpen) { | |
Log.d(LOG, "Клавиатура видна = " + isOpen); | |
KEYBOARD_VISIBLE = isOpen; | |
} | |
}); | |
} | |
//Смена вкладки | |
public void switchTab(int tabIndex, boolean needToRender) { | |
Log.d(LOG, "Смена вкладки = " + tabIndex); | |
//Смотрим видна клава ли нет ! | |
//Если она видна - то мы ее скрываем | |
if (KEYBOARD_VISIBLE) { | |
Instruments.getInstance().hideSoftKeyboard(rootActivity); | |
} | |
//Предотвращение NPE | |
if (navRouter == null) { | |
return; | |
} | |
//Смотрим на какой индекс перешли | |
IS_TAB_SWITCHED = tabIndex != 0; | |
List<RouterTransaction> backStack = navRouter.getBackstack(); | |
int newActiveIndex = -1; //Новый активный индекс = -1(Ничего не выбрано) | |
int oldActiveIndex = backStack.size() - 1; //Предыдущий выбранный индекс = ПОСЛЕДНИЙ В БЭКСТЕКЕ | |
//бЕЖИМ ПО БЭКСТЕКУ - С ПОСЛЕДНЕГО до первого | |
for (int i = oldActiveIndex; i >= 0; --i) { | |
RouterTransaction routerTransaction = backStack.get(i); //Берем текущую транзакцию | |
//Если новый контроллер отличается от того который сечас | |
if (routerTransactionList.get(tabIndex) != null && routerTransactionList.get(tabIndex).controller() != routerTransaction.controller()) { | |
continue; | |
} | |
//Мы сюда попадаем только после двух проверок | |
if (i != oldActiveIndex) { | |
newActiveIndex = i; | |
} | |
break; //и сразу выброс) | |
} | |
//Если новый индекс не равен -1 | |
//И он не равен тому на который сейчас меняем | |
if (newActiveIndex != -1) { | |
backStack.add(backStack.remove(newActiveIndex)); //Немного не понимаю | |
navRouter.setBackstack(backStack, null); | |
curSwitchIndex = tabIndex; | |
// currentRouter = backStack.get(backStack.size() - 1).controller().getChildRouter(); //Ставим в текущий роутер тот, который выбран в ботнаве | |
//Нужно какой то слушатель | |
// onActiveControllerChanged(); | |
} else { | |
return; | |
} | |
//Видимо вот тут придется делать сохранение состояния)))) | |
//И его восстановление | |
//Для боттом навигации! | |
//Выбираем текущий индекс боттом навигации | |
if (needToRender) { | |
ahBottomNavigation.setCurrentItem(tabIndex); | |
} | |
} | |
//Получение текущего активного контроллера(Навигационного) | |
protected Controller getNavController() { | |
if (navRouter == null) { | |
return null; | |
} | |
List<RouterTransaction> backStack = navRouter.getBackstack(); | |
if (backStack.isEmpty()) { | |
return null; | |
} | |
return backStack.get(backStack.size() - 1).controller(); | |
} | |
//переходи далее по роутеру(ФуллСкрин!) | |
public void goNext(BaseScreen screen) { | |
Log.d(LOG, "Переходим далее - ФуллСкрин"); | |
mainRouter.pushController(RouterTransaction | |
.with(screen) | |
.pushChangeHandler(new FadeChangeHandler()) | |
.popChangeHandler(new FadeChangeHandler())); | |
Log.d(LOG, "BackStack MAIN NEXT = " + mainRouter.getBackstack().size()); | |
} | |
//Метод перехода далее с установкой тага | |
public void goNextTag(BaseScreen screen, String tag) { | |
Log.d(LOG, "Переходим далее - ФуллСкрин С ТАГОМ"); | |
//Смотрим видна клава или нет ! | |
//Если да - то мы ее убираем! | |
if (KEYBOARD_VISIBLE) { | |
Instruments.getInstance().hideSoftKeyboard(rootActivity); | |
} | |
mainRouter.pushController(RouterTransaction | |
.with(screen) | |
.tag(tag) //Ставим таг!!!(На который потом сделаем выброс) | |
.pushChangeHandler(new FadeChangeHandler()) | |
.popChangeHandler(new FadeChangeHandler())); | |
Log.d(LOG, "BackStack MAIN NEXT TAG = " + mainRouter.getBackstack().size()); | |
} | |
//Метод выьроса на таг | |
public void popToTag(String tag) { | |
Log.d(LOG, "Выброс по ТАГУ"); | |
mainRouter.popToTag(tag); | |
Log.d(LOG, "BackStack MAIN POP TAG = " + mainRouter.getBackstack().size()); | |
} | |
//Переход далее - для ребенка | |
public void goNextChild(BaseScreen screen) { | |
Log.d(LOG, "Переходим далее - РЕБЕНОК"); | |
if (currentRouter == null) return; | |
currentRouter.pushController(RouterTransaction | |
.with(screen) | |
.pushChangeHandler(new FadeChangeHandler()) | |
.popChangeHandler(new FadeChangeHandler())); | |
Log.d(LOG, "BackStack CHILD = " + currentRouter.getBackstack().size()); | |
} | |
//Переход назад | |
//Переход назад - ИМЕННО НАЗАД, КНОПКОЙ БЭК | |
public void goBack() { | |
//Смотрим видна клава или нет ! | |
//Если да - то мы ее убираем! | |
if (KEYBOARD_VISIBLE) { | |
Instruments.getInstance().hideSoftKeyboard(rootActivity); | |
} | |
Log.d(LOG, "BackStack MAIN = " + mainRouter.getBackstack().size()); | |
//Если мы насильно установили ручную обработку кнпки назад!!! | |
if (customBackBtn) { | |
if (customBackBtnClicker != null) { | |
customBackBtnClicker.backClick(); | |
} | |
return; | |
} | |
//Если есть активный таг на который нужно пеерйти | |
if (mainRouter != null && mainRouter.getBackstackSize() > 1 && needToPopRoot) { | |
Log.d(LOG, "Главный роутер POP = " + mainRouter.getBackstackSize()); | |
needToPopRoot = false; | |
mainRouter.popToRoot(); | |
return; | |
} | |
//Если главный роутер не может перейти назад | |
if (mainRouter != null && mainRouter.getBackstackSize() > 1) { | |
Log.d(LOG, "Главный роутер назад = " + mainRouter.getBackstackSize()); | |
mainRouter.handleBack(); | |
return; | |
} | |
//Если дети могут перейти назад | |
if (currentRouter != null && currentRouter.getBackstackSize() > 0) { | |
Log.d(LOG, "Текущий роутер назад = " + currentRouter.getBackstackSize()); | |
currentRouter.handleBack(); | |
return; | |
} | |
//Если так оказалось что из ПОЛНОЭКРАННОГО РЕЖИМА НИЧЕГО НЕ ВЫТАЛКИВАЕТСЯ, | |
//то мы проверяем - МБ мы просто сменили вкладку на корневых экранах ??? | |
if (IS_TAB_SWITCHED) { | |
Log.d(LOG, "Смена вкладки назад"); | |
switchTab(0, true); | |
} else { | |
if (rootActivity == null) return; | |
//Если это корневое активити - то ПРОСТО НАХУЙ ЗАКРЫВАЕМ ПРИЛОЖЕНИЕ | |
rootActivity.finishAffinity(); | |
} | |
} | |
//Получение видимости клавы! | |
public Boolean getKEYBOARD_VISIBLE() { return KEYBOARD_VISIBLE; } | |
public ViewGroup getFullScreenContainer() { | |
return fullScreenContainer; | |
} | |
public void setFullScreenContainer(ViewGroup fullScreenContainer) { | |
this.fullScreenContainer = fullScreenContainer; | |
} | |
public ViewGroup getBotNavContainer() { | |
return botNavContainer; | |
} | |
public void setBotNavContainer(ViewGroup botNavContainer) { | |
this.botNavContainer = botNavContainer; | |
} | |
//Все что нужно для боттом навигации | |
//Примерно тоже самое будет нужна для дровера | |
public AHBottomNavigation getBottomNavigationView() { | |
return ahBottomNavigation; | |
} | |
//Установка навигации | |
public void setBottomNavigationView(AHBottomNavigation ahBottomNavigation, | |
List<RouterTransaction> routerTransactionList, | |
Router navRouter) { | |
this.ahBottomNavigation = ahBottomNavigation; | |
this.navRouter = navRouter; | |
this.routerTransactionList = routerTransactionList; | |
//Все транзакции загоняем в роутер | |
for (RouterTransaction routerTransaction : routerTransactionList) { | |
this.navRouter.pushController(routerTransaction); | |
} | |
//Добавляем элементы! | |
AHBottomNavigationItem item1 = new AHBottomNavigationItem("Назначенные", R.drawable.calendar_10x); | |
AHBottomNavigationItem item2 = new AHBottomNavigationItem("В работе", R.drawable.technical_support_10x); | |
AHBottomNavigationItem item3 = new AHBottomNavigationItem("Осмечивание", R.drawable.list_10x); | |
AHBottomNavigationItem item4 = new AHBottomNavigationItem("Согласование", R.drawable.group_10x); | |
this.ahBottomNavigation.addItem(item1); | |
this.ahBottomNavigation.addItem(item2); | |
this.ahBottomNavigation.addItem(item3); | |
this.ahBottomNavigation.addItem(item4); | |
// this.ahBottomNavigation.addItem(item5); | |
//Меняем цвет активной иконки ! | |
ahBottomNavigation.setAccentColor(Color.parseColor("#26245C")); | |
this.ahBottomNavigation.setOnTabSelectedListener(new AHBottomNavigation.OnTabSelectedListener() { | |
@Override | |
public boolean onTabSelected(int position, boolean wasSelected) { | |
CoordinatorMain.getInstance().switchTab(position, true); | |
return true; | |
} | |
}); | |
//Выбираем 0 индекс(Изначально) | |
switchTab(0, true); | |
} | |
public Router getMainRouter() { | |
return mainRouter; | |
} | |
public void setMainRouter(Router mainRouter) { | |
this.mainRouter = mainRouter; | |
} | |
public void setCustomBackBtn(Boolean customBackBtn) { | |
this.customBackBtn = customBackBtn; | |
} | |
public void setCustomBackBtnClicker(CustomBackBtnClicker customBackBtnClicker) { | |
this.customBackBtnClicker = customBackBtnClicker; | |
} | |
public Boolean getNeedToPopRoot() { | |
return needToPopRoot; | |
} | |
public void setNeedToPopRoot(Boolean needToPopRoot) { | |
this.needToPopRoot = needToPopRoot; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment