Страницы

Поиск по вопросам

суббота, 1 июня 2019 г.

Android: правильное использование фрагментов и Navigation Drawer

Я использую в приложении шаблон Navigation Drawer Activity и у меня возникли несколько вопросов по поводу правильного использования его и фрагментов в целом.
Т.к. все страницы (назову фрагменты, открываемые из бокового меню так) приложения - фрагменты в одной активити, то я лишаюсь возможности использовать Intent для переключения активиностей? Как реализовать открытие фрагмента (какой-то страницы) по какому-то действию из другого фрагмента? Сделать интерфейс, напримерIFragmentAction, со всеми событиями, которые могут послать фрагменты, реализовать его у активити и вызывать эти методы из фрагментов? А в них уже делать транзакции? Это правильно? Аналогично, если нужно по действию во фрагменте показать фрагмент, не явлюящийся "страницей" - надо делать аналогично, через активити? Или можно сделать транзакцию прямо из фрагмента (в настоящий момент сделал так, но кажется это немного неправильно) Если нужен режим для планшета, где некоторые фрагменты не открываются поверх старых, а расположены рядом - надо создать новый layouyt еще одну активити, реализующую интерфейс, но с другим поведением? Или это не самый правильный подход? Как правильно вернуть результат из DialogFragment? Я реализовывал интерфейс у фрагмента, который вызывал этот диалог, через который диалог устанавливал нужные значения. Кажется, не лучший подход. Столкнулся с такой проблемой: Если после нескольких смен фрагментов пользователь переходит через боковое меню на другую страницу - он видит несколько наложившихся активностей. Если просто сделать белый фон - задняя активность все равно останется кликабельной.
Как правильно сделать переходы между активностями, чтобы не возникало таких проблем и чтобы это было правильно?


Ответ

Отвечу на всю историю примерным кодом.
Пусть Ваш NavigationDrawer содержит кастомный адаптер для списка. При нажатии в списке на элемент вы к примеру получите йд нужного фрагмента, пусть это будет int, Но лучше строка. Получаем TAG Фрагмента.
private String getTagById(int tagId) { String tag = null; if (Frag1.TAG_ID == tagId) { tag = Frag1.TAG; } else if (Frag2.TAG_ID == tagId) { tag = Frag2.TAG; } return tag; }
Дальше в роль вступает участок кода для работы с фрагментами. В нем мы узнаем совпадает ли активный фрагмент с выбранным, если не совпадает мы сделаем detach активного, проверим открывали ли ранее выбранный и выполним replace или attach
private void showFragment(String tag) { String oldTag = mSelectedTag; mSelectedTag = tag; final FragmentManager fm = getSupportFragmentManager(); final FragmentTransaction ft = fm.beginTransaction(); final Fragment oldFragment = fm.findFragmentByTag(oldTag); final Fragment fragment = fm.findFragmentByTag(tag);
if (oldFragment != null && !tag.equals(oldTag)) { ft.detach(oldFragment); }
if (fragment == null) { ft.replace(R.id.container, getContentFragment(tag), tag); } else { if (fragment.isDetached()) { ft.attach(fragment); } } ft.commit(); }
Этот кусок кода отдает нужный фрагмент по тагу.
private Fragment getContentFragment(String tag) { Fragment fragment = null; if (Frag1.TAG.equals(tag)) { fragment = new Frag1(); } else if (Frag2.TAG.equals(tag)) { fragment = new Frag2(); } return fragment; }
А вот так все запускаем:
@SuppressWarnings("StatementWithEmptyBody") @Override public boolean onNavigationItemSelected(MenuItem item) { showFragment(getTagById(item.getItemId())); DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); drawer.closeDrawer(GravityCompat.START); return true; }

Комментариев нет:

Отправить комментарий