android - studio - Inflando AppBarLayout con la barra de herramientas+TabLayout
tabs android studio example (7)
Actualmente tengo un DrawerLayout en mi main.xml. Hay una barra de herramientas envuelta en un AppBarLayout, y luego un simple LinearLayout para intercambiar fragmentos.
Uno de los fragmentos a los que navego, quiero que contenga un TabLayout para un ViewPager de fragmentos. Actualmente, tengo ambos elementos en el archivo de diseño del fragmento, pero esto hace que aparezca una sombra paralela entre la Barra de herramientas y el TabLayout, que es algo que no quiero. Tampoco quiero usar setElevation () porque no funcionará para dispositivos pre-Lollipop.
Una posible solución sería inflar el AppBarLayout de mi fragmento, de modo que contenga tanto la Barra de herramientas como las Tabs. Sin embargo, no estoy muy seguro de cómo hacer esto, por lo que cualquier ayuda sería apreciada.
Aquí está mi archivo main.xml:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.lumivote.lumivote.ui.MainActivity">
<android.support.design.widget.CoordinatorLayout
android:id="@+id/rootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<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="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
</android.support.design.widget.AppBarLayout>
<LinearLayout
android:id="@+id/flContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="@+id/navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/nav_header"
app:itemIconTint="#333"
app:itemTextColor="#333"
app:menu="@menu/navigation_drawer_items" />
</android.support.v4.widget.DrawerLayout>
Y aquí está el archivo xml de mi fragmento:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.alexdao.democracy.ui.candidate_tab.CandidateListFragment">
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/myPrimaryColor"
app:tabMode="fixed"
app:tabGravity="fill"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white" />
</LinearLayout>
El enfoque funcionó para mí con algunas modificaciones.
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
...
mTabLayout = (TabLayout) inflater.inflate(
R.layout.partial_tab_layout,
container,
false);
mAppBarLayout = (AppBarLayout) getActivity().findViewById(R.id.app_bar);
mAppBarLayout.addView(mTabLayout,
new LinearLayoutCompat.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
...
}
Y eliminando la vista en onDestroyView()
@Override
public void onDestroyView() {
mAppBarLayout.removeView(mTabLayout);
super.onDestroyView();
}
La solución es simple en el XML. Solo agrega el siguiente código a tu AppBarLayout: app:elevation="0dp"
. Así que el AppBarLayout debería verse así:
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="0dp"
android:theme="@style/AppTheme.AppBarOverlay">
Modifiqué la solución dada por el bleeding182 y también la hice funcionar para AppBarLayout (para resolver el problema señalado por bopa ).
@Override
public void onAttach(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getActivity().findViewById(R.id.appbar).setElevation(0);
}
super.onAttach(context);
}
@Override
public void onDetach() {
super.onDetach();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getActivity().findViewById(R.id.appbar).setElevation(R.dimen.toolbar_elevation);
}
}
Lo que hice fue reemplazar la llamada a getSupportActionBar () al dar una ID a mi AppBarLayout y luego llamar a findViewById () y luego llamar a setElevation en su resultado. Probado en API 23.
Para solucionar mi problema, terminé poniendo la barra de herramientas, TabLayout y ViewPager en mi MainActivity.
main_activity.xml:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.CoordinatorLayout
android:id="@+id/rootLayout"
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:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabGravity="fill"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white" />
</android.support.design.widget.AppBarLayout>
<RelativeLayout
android:id="@+id/flContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="@+id/navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/nav_header"
app:itemIconTint="#333"
app:itemTextColor="#333"
app:menu="@menu/navigation_drawer_items" />
</android.support.v4.widget.DrawerLayout>
Luego, en todos mis fragmentos, programé la visibilidad para el TabLayout y el ViewPager programáticamente en onCreateView:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
TabLayout tabLayout = (TabLayout) getActivity().findViewById(R.id.tabLayout);
tabLayout.setVisibility(View.GONE);
ViewPager mViewPager = (ViewPager) getActivity().findViewById(R.id.viewpager);
mViewPager.setVisibility(View.GONE);
return inflater.inflate(R.layout.fragment_layout, container, false);
}
Por supuesto, en el fragmento con pestañas, desearía establecer la visibilidad en View.VISIBLE
lugar de View.GONE
.
Puedes tener una barra de herramientas separada para cada fragmento. Es posible configurar la barra de herramientas de fragmentos como la barra de acción de la actividad. Código de ejemplo:
Toolbar toolbar = (Toolbar) v.findViewById(R.id.toolbar);
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
Debería ser posible tener títulos, íconos y otras cosas también. Con él puedes imitar la sombra en los dispositivos de pre-piruleta, sin importar lo que tengas en ellos.
Simplemente puede agregar TabLayout mediante programación desde Fragmento en el que necesite TabLayout
tabLayout = (TabLayout) inflater.inflate(R.layout.tablay, null);
appBarLayout = (AppBarLayout) getActivity().findViewById(R.id.appbar);
appBarLayout.addView(tabLayout, new LinearLayoutCompat.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
y elimine TabLayout de AppBar en onDetach ()
@Override
public void onDetach() {
appBarLayout.removeView(tabLayout);
super.onDetach();
}
Tuve un problema similar en el que quería un TabLayout
justo dentro de un fragmento.
Sin cambiar ningún otro código, puede resolver esto utilizando onAttach
y onDetach
dentro de su fragmento con el TabLayout.
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// todo add some further checks, e.g. instanceof, actionbar != null
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
((AppCompatActivity) activity).getSupportActionBar().setElevation(0);
}
}
@Override
public void onDetach() {
super.onDetach();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
((AppCompatActivity) getActivity()).getSupportActionBar()
.setElevation(getResources().getDimension(R.dimen.toolbar_elevation));
}
}
¡Asegúrese de establecer la misma elevación en su TabLayout y todo funciona bien! ;RE