Android: есть ли способ скрыть элементы макета MainActivity во фрагментах?

Мой макет MainActivity включает нижнюю панель навигации, потому что я хотел бы использовать ее в качестве основных компонентов навигации во фрагментах моего приложения. Однако у меня есть страница входа, на которой я не хочу видеть панель навигации. Поскольку фрагмент создается из MainActivity, он наследует панель навигации, и я не могу найти способ скрыть ее во фрагменте входа и показать в последующих фрагментах.

Для удобства:

  1. У меня есть макет MainActivity с BottomNavigationBar
  2. Все фрагменты изначально наследуют BottomNavigationBar из макета MainActivity.
  3. Я хочу, чтобы видимость панели навигации была «ИСКЛЮЧЕНА» во фрагменте входа пользователя.
  4. Я хочу, чтобы видимость панели навигации была "ВИДИМОЙ" на остальных фрагментах

Есть ли способ сделать это?

Причина, по которой я определяю BottomNavigationBar в MainActivity, заключается в том, что изначально у меня была отдельная панель навигации для каждого фрагмента, которая требовала отдельных слушателей для каждого фрагмента (что делало код более обширным, чем должен быть). Кроме того, когда я реализовал панель навигации как отдельный компонент в каждом фрагменте, анимация выбранного элемента больше не функционировала.

Я пытался использовать <include layout="@layout/main_activity android:visibility="GONE" android:layout_width="match_parent" android:layout_height="wrap_content"/> из фрагмента входа в систему, но это не сработало.

Я был бы признателен за любую помощь людей в этом вопросе.

Пожалуйста, не стесняйтесь, дайте мне знать, если вы хотите увидеть какой-либо из моих кодов. Я не был уверен, какие части моего кода будут актуальны.


person Oliver Williams    schedule 06.02.2020    source источник


Ответы (2)


Я бы посоветовал вам использовать для этого случая отдельные действия — LoginActivity и MainActivity. Так как вы можете в какой-то момент добавить ForgotPasswordFragment и, возможно, что-то еще. ИМХО, скрывать то, что вам изначально не нужно, - плохая практика.

Если вы не хотите менять свой подход, вы можете создать BaseFragment, который будет иметь abstract val showBottomNavBar() и будет override в каждом фрагменте. А затем в onViewCreated вы проверите этот флаг и соответствующим образом обновите пользовательский интерфейс.

Что-то вроде этого:

abstract class BaseFragment : Fragment() {
  abstract val showBottomNavBar: Boolean
  //.. your other stuff
}

class FragmentA : BaseFragment() {
  override val showBottomNavBar = false

  override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    if (!showBottomNavBar) {
      (requireActivity() as YourAcitivy).hideNavBar() //this is bad
      someKindOfBroadcastManager.sendEvent(hideNavBar) // this is somewhat better
    }
  }
} 

Но я бы все же посоветовал вам отделить логику входа/основной логики от одного действия.

person Alex Grebennikov    schedule 06.02.2020
comment
Я понимаю. Итак, в этом случае вы бы предложили мне сделать экран входа в систему начальной активностью, которая представлена ​​​​пользователю (а не фрагментом), а затем, как только они успешно войдут в систему, класс входа запустит StartActivity (MainActivity), в котором размещены фрагменты? - person Oliver Williams; 06.02.2020
comment
Вот что сработало для меня лучше всего. SplashActivity — это запуск приложения. Он проверяет, вошел ли пользователь в систему или нет. В зависимости от этого вы начинаете следующее действие всякий раз, когда оно входит в систему или является основным. Вы можете сделать что-то подобное, комбинируя всплеск и вход в систему, если хотите меньше действий. - person Alex Grebennikov; 06.02.2020

Вы можете получить доступ к активности из фрагмента с помощью метода getActivity() и применить к своей активности. Конечно, вы должны добавить метод hideBottomNavigationBar в свою активность, а также вы должны быть уверены, что ваша активность хоста фрагментов - это MyActivity.

MyActivity activity = ((MyActivity)getActivity());
activity.hideBottomNavigationBar();

После этого вы можете определить интерфейс маркера с именем IFullScreen, а затем в методе onCreateView вашего BaseFragment вы можете проверить, является ли этот класс экземпляром IFullScreen, и решить, показать или скрыть нижнюю панель навигации.

interface IFullScreen { }

class BaseFragment extends Fragment {

    @CallSuper
    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        MyActivity activity = ((MyActivity)getActivity());
        if (this instanceof IFullScreen)
            activity.hideBottomNavigationBar();
        else 
            activity.showBottomNavigationBar();
    }

}

class FragmentA extends BaseFragment implements IFullScreen {

    //Rest of fragment code
}
person toffor    schedule 06.02.2020
comment
Буду ли я использовать этот код из фрагмента (LoginFragment.java) или из файла MainActivity.java? - person Oliver Williams; 06.02.2020
comment
Если вы создали свой фрагмент с помощью менеджера фрагментов MainActivity, то да, вы можете использовать. Также я добавил фрагмент кода. - person toffor; 06.02.2020