android - example - Usando navigationView con tabLayout
tablayout with icons (3)
No puedo recomendar lo que Yiyo sugirió. Si va a tener Fragmentos con diferentes diseños, debe permitir que los Fragmentos personalicen estos diseños en el XML. Esta es la razón por la que la introducción de la barra de herramientas tiene tanto sentido para el desarrollo de Android. En el futuro, es posible que tenga más requisitos que difieran entre cada Fragmento. Es posible que algunos de ellos no quieran una Barra de herramientas, otros que necesiten otra Vista sobre la Barra de herramientas, algunos de ellos tendrán un RecyclerView al que le gustaría que el CoordinatorLayout y AppBar accedan para que el comportamiento de desplazamiento funcione correctamente.
Le recomiendo que solo coloque un FrameLayout como contenido de su DrawerLayout (como mencionó Yiyo en el punto 1). Aquí cargará cada Fragmento de las devoluciones de llamada de 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>
En el XML de cada Fragmento, colocará, si así lo requiere ese Fragmento, una Barra de Herramientas. En el XML de su fragmento con pestañas, colocará el TabLayout y, si así lo desea, el CoordinatorLayout y el AppBarLayout. De cada fragmento que tiene una barra de herramientas, establecerá la barra de herramientas como la barra de acción:
Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
AppCompatActivity activity = (AppCompatActivity) getActivity();
activity.setSupportActionBar(toolbar);
Eso es todo al respecto. Por supuesto, no quieres repetirte en cada Fragmento, por lo que puedes, por ejemplo, poner este código en un DrawerFragment y subclasificarlo para fragmentos con una Barra de herramientas. También querrá poner la configuración XML de su barra de herramientas en un solo archivo e incluirla en el fragmento XML <include layout="@layout/toolbar" />
. O tal vez desee eliminar la barra de herramientas de algunos fragmentos o cambiar su color, tema, etc.
Así que recientemente he estado trabajando en actualizar mi aplicación para usar la nueva biblioteca de soporte de diseño de materiales. Mi aplicación tiene una actividad principal con un drawerLayout y una vista de navegación. El contenido principal de la aplicación se muestra en un frameLayout, a través de fragmentos. Sin embargo, ahora estoy intentando agregar pestañas de material a uno de los fragmentos del cajón de navegación. Sin embargo, no estoy seguro de cómo implementar esto mientras se mantienen mis fragmentos en el cajón de navegación. A continuación se muestra un buen ejemplo de lo que estoy tratando de lograr:
En esta aplicación (Google play music), solo algunos de los elementos del cajón de navegación tienen pestañas, mientras que otros no. Entonces mi pregunta es, ¿cómo implementaría esto? (No busco código, solo una descripción general de cómo debería organizarse mi diseño)
Para resumir / aclarar: tengo un diseño principal con un frameLayout (para el contenido de mi aplicación) y un navigationView (para navegar por los diferentes fragmentos de elementos). Luego tengo un oyente que reemplaza el frameLayout del diseño principal con el fragmento respectivo del elemento. Ahora, necesito agregar pestañas a solo uno de estos fragmentos (para navegar entre otros 4 fragmentos). También estoy usando una barra de herramientas que incluyo como un diseño separado.
Cualquier consejo es apreciado. Lo siento si mi descripción es un poco confusa; Voy a aclarar los detalles necesarios.
Ok, supongamos que su NavigationView tiene dos opciones, la primera muestra el fragmento con pestañas (diseño de pestaña) y la segunda muestra solo un fragmento con una barra de herramientas. Tienes dos opciones entonces:
- Puede tener un diseño principal con solo un diseño de marco y reemplazarlo con todo lo que desee
- Puede tener un diseño principal con diseño coordinador -> barra de aplicaciones -> barra de herramientas -> diseño de pestañas y un diseño de marco para colocar contenido
Prefiero la segunda opción para evitar tener que configurar siempre la barra de herramientas, así que esto fue lo que hice una vez:
<!-- 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>
Como ves, cambio la visibilidad de TabLayout a "ido" para que el fragmento con pestañas tenga cuidado de establecerlo como visible. El fragmento con las pestañas solo tiene el ViewPager en el diseño:
<!-- 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" />
Ahora el fragmento con pestañas inicializa el ViewPager con los fragmentos para cada página:
@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);
}
Y finalmente, haga lo que quiera en sus TabFragments, esto funciona bien para mí y espero que esto también sea útil para usted. Disculpe por algún problema con la sintaxis de código, desarrollo Android con Kotlin y no con Java.
Puedes hacerlo así. Lo he comprobado haciéndolo yo mismo y funciona muy bien.
Paso 1: Crea un diseño de tu actividad principal como este
<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" />
Paso 2 :
En tu actividad necesitas configurar onpagechangelistener en tu 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) {
}
});
Después de esto, debe agregar viewPager.addOnPageChangeListener (nuevo TabLayout.TabLayoutOnPageChangeListener (tabLayout));
Paso 3 :
Así es como puedes hacer tu adaptador para viewpager:
La clase pública WiFiPagerAdapter extiende FragmentPagerAdapter {Lista final privada registeredFragments = 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();
}
}
}