Подтвердить что ты не робот

Использование navigationView с tabLayout

Итак, я недавно занимался обновлением своего приложения, чтобы использовать библиотеку поддержки новых материалов. Мое приложение имеет одно основное действие с помощью drawerLayout и навигации. Основное содержание приложения показано в frameLayout через фрагменты. Однако теперь я пытаюсь добавить вкладки материалов к одному из фрагментов ящика навигации. Тем не менее, я не уверен, как это реализовать, сохраняя мои фрагменты в ящике навигатора. Хороший пример того, что я пытаюсь достичь, показан ниже:

введите описание изображения здесь

В этом приложении (Google play music) только некоторые элементы навигационного элемента имеют вкладки, а другие - нет. Итак, мой вопрос: как мне это реализовать? (Не ища код, просто обзор того, как мой макет должен быть организован)

Повторить/пояснить: У меня есть основной макет с frameLayout (для моего содержимого приложения) и navigationView (для навигации по различным фрагментам элементов). Затем у меня есть слушатель, который заменяет основной макет frameLayout элементом соответствующего фрагмента. Теперь мне нужно добавить вкладки только к одному из этих фрагментов (для перемещения между 4-мя другими фрагментами). Я также использую панель инструментов, которую я включаю в качестве отдельной компоновки.

Любые советы приветствуются. Извините, если мое описание немного запутанно; Я уточню все необходимые детали.

4b9b3361

Ответ 1

Я не могу рекомендовать то, что предложил Йиё. Если вы собираетесь иметь фрагменты с разными макетами, вы должны позволить Fragments настраивать эти макеты в XML. Вот почему введение панели инструментов имеет столь большое значение для разработки Android. В будущем у вас может быть даже больше требований, которые различаются между каждым фрагментом. Некоторым из них может не понадобиться панель инструментов, для некоторых из них может потребоваться другой вид над панелью инструментов, некоторые из них будут иметь RecyclerView, которые вы хотели бы получить доступ к CoordinatorLayout и AppBar, чтобы поведение прокрутки работало правильно.

Я рекомендую вам помещать только FrameLayout в качестве содержимого вашего DrawerLayout (как Yiyo, упомянутого в пункте 1). Здесь вы будете загружать каждый фрагмент из обратных вызовов NavigationView.

<android.support.v4.widget.DrawerLayout 
    ...
    android:fitsSystemWindows="true"
    >

    <FrameLayout
        android:id="@+id/drawer_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <android.support.design.widget.NavigationView
        ...
        />

</android.support.v4.widget.DrawerLayout>

В каждом фрагменте XML вы поместите, если потребуется, этот фрагмент, панель инструментов. В вашем XML-фрагменте Fragment вы поместите TabLayout и, если хотите, координаторLayout и AppBarLayout. Из каждого фрагмента, имеющего панель инструментов, вы установите панель инструментов как ActionBar:

Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
AppCompatActivity activity = (AppCompatActivity) getActivity();
activity.setSupportActionBar(toolbar);

Вот и все. Конечно, вы не хотите повторять себя во всех фрагментах, так что вы можете, например, поместить этот код в DrawerFragment и подклассировать его для фрагментов с помощью панели инструментов. Вы также захотите поместить XML-конфигурацию панели инструментов в один файл и включить ее в XML-фрагмент фрагмента <include layout="@layout/toolbar" />. Или вы можете удалить панель инструментов из некоторых фрагментов или изменить цвет, тему и т.д.

Ответ 2

Хорошо, предположим, что ваш NavigationView имеет две опции, первая показывает фрагмент с вкладками (макет табуляции), а второй показывает только фрагмент с панелью инструментов. У вас есть два варианта:

  • Вы можете иметь основной макет только с макетом фрейма и заменять его всем, что хотите.
  • У вас может быть основной макет с макетом координатора → панель приложений → панель инструментов → макет вкладки и макет кадра для размещения контента

Я предпочитаю второй вариант, чтобы избежать необходимости всегда настраивать панель инструментов, так что это то, что я сделал один раз:

<!-- layout_main -->
<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <android.support.design.widget.CoordinatorLayout
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <android.support.v7.widget.Toolbar                    
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:layout_scrollFlags="scroll|enterAlways"/>

            <android.support.design.widget.TabLayout
                android:id="@+id/tab_layout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:visibility="gone"
                app:tabGravity="fill"
                app:tabMode="fixed" />

        </android.support.design.widget.AppBarLayout>

        <FrameLayout
            android:id="@+id/main_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    </android.support.design.widget.CoordinatorLayout>

    <!-- The NavigationView -->
    <fragment
        android:id="@+id/navigation_fragment"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:name="some.path.to.the.NavigationViewFragment"
        tools:layout="@layout/fragment_navigation_view" />

</android.support.v4.widget.DrawerLayout>

Как вы видите, я изменяю видимость TabLayout на "ушел", чтобы фрагмент с вкладками старался установить как видимый. Фрагмент с вкладками имеет только ViewPager в макете:

<!-- fragment_with_tabs -->
<android.support.v4.view.ViewPager
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/view_pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Теперь фрагмент с вкладками инициализирует ViewPager фрагментами для каждой страницы:

@Override 
public onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    // The getChildFragmentManager() is Very important! Because fragments inside fragments are
    // not supported with the tipical fragmentManager, it requires NestedFragments and those
    // uses a childFragmentManager(). In other case a strange behaviour occurs
    ViewPagerAdapter adapter = new ViewPagerAdapter(getChildFragmentManager());
    adapter.addFragment(new TabOneFragment(), "Tab 1");
    adapter.addFragment(new TabTwoFragment(), "Tab 2");
    viewPager.setAdapter(adapter);

    tabLayout = (TabLayout) getActivity().findViewById(R.id.tab_layout);
    tabLayout.setVisibility(View.VISIBLE);
    tabLayout.setupWithViewPager(viewPager);
}

И, наконец, сделайте все, что захотите, в своих вкладках, это отлично работает для меня, и я надеюсь, что это тоже будет полезно для вас. Извините за некоторые проблемы с синтаксисом кода, я разрабатываю андроид с Kotlin, а не с Java.

Ответ 3

Вы можете сделать это так. Я проверил, сделав это сам, и он работает очень хорошо.

Шаг 1: Создайте макет своего основного вида, например

  

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appBarLayout" android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar" android:layout_width="match_parent"
            android:layout_height="wrap_content" android:background="@color/blue"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            android:titleTextAppearance="@style/TextAppearance.AppCompat.Small"
            app:layout_scrollFlags="scroll|enterAlways" />

        <android.support.design.widget.TabLayout
            android:id="@+id/tab_layout" style="@style/FreeWiFiTabLayout"
            android:layout_width="match_parent" android:layout_height="wrap_content"
            android:layout_gravity="center" android:background="@color/blue"
            android:visibility="gone" android:fitsSystemWindows="true"
            android:minHeight="?attr/actionBarSize" />
    </android.support.design.widget.AppBarLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/wifi_type_pager" android:layout_width="match_parent"
        android:layout_height="match_parent" android:clipToPadding="false"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
<fragment android:id="@+id/navigation_drawer"
    android:name="com.easyway.freewifi.NavigationDrawerFragment"
    android:layout_width="wrap_content" android:layout_height="match_parent"
    android:layout_gravity="start|bottom" android:layout_marginTop="?attr/actionBarSize"
    tools:layout="@layout/navigation_drawer_fragment" />

Шаг 2:

В вашей деятельности вам нужно установить onpagechangelistener на вашем viewpager:

 viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
  @Override
  public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

  }

  @Override
  public void onPageSelected(int position) {
        if(position ==0){
          tabLayout.setVisibility(View.GONE);
        }else{
          tabLayout.setVisibility(View.VISIBLE);
        }
  }

  @Override
  public void onPageScrollStateChanged(int state) {

  }
});

После этого вам нужно добавить  viewPager.addOnPageChangeListener(новый TabLayout.TabLayoutOnPageChangeListener(tabLayout));

Шаг 3:

Вот как вы можете сделать свой адаптер для viewpager:

открытый класс WiFiPagerAdapter расширяет FragmentPagerAdapter {   private final Список зарегистрированныхFragments = new ArrayList < > ();

public WiFiPagerAdapter(final FragmentManager fm) {
  super(fm);
}

@Override
public Fragment getItem(final int pos) {
  Fragment fragment;
  fragment = WiFiFragment.newInstance(pos);
  registeredFragments.add(pos, fragment);
  return fragment;
}

@Override
public int getCount() {
  return tabLayout.getTabCount();
}

public List<Fragment> getRegisteredFragmentsList() {
  return registeredFragments;
}

@Nullable
public Fragment getRegisteredFragment(final int position) {
  final Fragment wr = registeredFragments.get(position);
  if (wr != null) {
    return wr;
  } else {
    return null;
  }
}

@Override
public void notifyDataSetChanged() {
  super.notifyDataSetChanged();
  for (int i = 0; i < registeredFragments.size(); i++) {
    WiFiFragment wiFiFragment = ((WiFiFragment) registeredFragments.get(i));
    wiFiFragment.setWiFiFragmentRecyclerViewAdapter();
  }
}

}