support library last android android-support-library android-design-library

library - ¿Cómo agregar pie de página a NavigationView-Biblioteca de diseño de soporte de Android?



com.android.support:support-v4 28 (23)

¿Cómo puedo establecer la configuración del pie de página y los elementos del perfil en NavitationView ? se parece a la bandeja de entrada por correo electrónico de navegación. Los elementos de NavitationView están inflados por recurso de menú, pero no sé cómo establecer elementos inferiores en un recurso de menú, o cómo puedo configurar una vista personalizada para NavigationView o un desplazamiento inferior. He intentado poner esto <LinearLayout...> como vista de pie de página, pero en pantallas pequeñas el pie de página coloca los elementos y no puedo desplazar el menú, he intentado establecer un relleno de pie de página en NavigationView , pero el pie de página también toma el relleno .

Esto no se desplaza en pantallas pequeñas:

<android.support.design.widget.NavigationView android:id="@+id/drawer" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" app:headerLayout="@layout/kuona_drawer_header" app:menu="@menu/drawer"> <LinearLayout...> </android.support.design.widget.NavigationView>

Esto se desplaza, pero el pie de página está sobre los elementos del menú:

<android.support.design.widget.NavigationView android:id="@+id/drawer" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:paddingBottom="96dp" app:headerLayout="@layout/kuona_drawer_header" app:menu="@menu/drawer"> <LinearLayout...> </android.support.design.widget.NavigationView>

Archivo del menú del cajón res/menu/drawer.xml :

<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <group android:checkableBehavior="single"> <item android:id="@+id/action_current_list" android:checked="true" android:icon="@drawable/ic_current_list" android:title="@string/current_list" /> <item android:id="@+id/action_manage_lists" android:icon="@drawable/ic_my_lists" android:title="@string/my_lists" /> <item android:id="@+id/action_search_products" android:icon="@drawable/ic_search_black_24dp" android:title="@string/search_products" /> <item android:id="@+id/action_deals" android:icon="@drawable/ic_product_promo" android:title="@string/deals" /> </group> </menu>


Esto está funcionando para mí para poner imágenes en el pie de página del cajón de navegación (orientación vertical y horizontal)

<?xml version="1.0" encoding="utf-8"?> <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/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:openDrawer="start"> <include layout="@layout/app_bar_main3" android:layout_width="match_parent" android:layout_height="match_parent" /> <android.support.design.widget.NavigationView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="start" android:background="#f00" android:fitsSystemWindows="true" app:menu="@menu/activity_main3_drawer"> <android.support.v4.widget.NestedScrollView android:layout_width="match_parent" android:fillViewport="true" android:layout_height="match_parent" android:scrollbars="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <android.support.design.widget.NavigationView android:id="@+id/nav_view" app:elevation="0dp" android:layout_height="wrap_content" android:layout_width="match_parent" android:background="#ff0" app:headerLayout="@layout/nav_header_main3" app:menu="@menu/activity_main3_drawer"> ></android.support.design.widget.NavigationView> <LinearLayout android:id="@+id/spacer_to_bottom" android:layout_width="match_parent" android:orientation="vertical" android:background="#0f0" android:layout_height="0dp" android:layout_weight="1"> <include layout="@layout/nav_footer_main3"></include> </LinearLayout> </LinearLayout> </android.support.v4.widget.NestedScrollView> </android.support.design.widget.NavigationView> </android.support.v4.widget.DrawerLayout>

mi nav_footer_main3 es

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="60dp"> <ImageView android:id="@+id/imageView" android:layout_gravity="center_horizontal" android:layout_width="200dp" android:layout_height="50dp" android:background="@drawable/logo_1" /> </LinearLayout>


Aquí hay una solución que no requiere anidamiento y que ajusta dinámicamente el relleno inferior de NavigationMenuView interno en función de la altura de la vista del pie de página, lo que significa que la altura del pie de página se puede establecer wrap_content y puede cambiar dinámicamente la visibilidad del pie de página VISIBLE o GONE .

public class NavigationMenuFooterView extends LinearLayout { public NavigationMenuFooterView(Context context) { super(context); } public NavigationMenuFooterView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } public NavigationMenuFooterView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onVisibilityChanged(@NonNull View changedView, int visibility) { update(getHeight()); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { update(h); } private void update(int height) { ViewParent parent = getParent(); if (parent instanceof ViewGroup) { View navigationMenuView = ((ViewGroup) parent).findViewById(R.id.design_navigation_view); if (navigationMenuView != null) { if (getVisibility() == View.GONE) { height = 0; } navigationMenuView.setPadding(navigationMenuView.getPaddingLeft(), navigationMenuView.getPaddingTop(), navigationMenuView.getPaddingRight(), height); } } } }

Debe definir la identificación de design_navigation_view en su ids.xml:

<?xml version="1.0" encoding="utf-8"?> <resources> <item name="design_navigation_view" type="id"/> </resources>

Y use así:

<com.google.android.material.navigation.NavigationView android:id="@+id/navigation_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" app:headerLayout="@layout/drawer_header" app:itemBackground="@drawable/drawer_item" app:itemIconTint="@color/drawer_item" app:itemTextColor="@color/drawer_item" app:menu="@menu/menu_drawer"> <util.NavigationMenuFooterView android:id="@+id/navigation_footer_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:background="#fff" android:orientation="vertical"> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="#ddd" /> <include layout="@layout/..." /> </util.NavigationMenuFooterView> </com.google.android.material.navigation.NavigationView>

Probado con com.google.android.material:material:1.0.0 .


Así es como logro agregar un diseño en la parte inferior de la navegación:

<android.support.design.widget.NavigationView android:id="@+id/navigation_drawer_container" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start"> <android.support.v4.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:weightSum="1"> <android.support.design.widget.NavigationView android:id="@+id/nav_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_gravity="top" android:layout_weight="0.8" app:headerLayout="@layout/nav_header_home" app:menu="@menu/activity_home_drawer" /> <android.support.design.widget.NavigationView android:id="@+id/navigation_drawer_bottom" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_below="@+id/nav_view" android:layout_weight="0.2"> <LinearLayout android:id="@+id/linearLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_below="@+id/scrollView" android:orientation="vertical"> <TextView android:id="@+id/text_dashboard_followUsAt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="16dp" android:paddingStart="16dp" android:text="Follow us at" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:paddingLeft="16dp" android:paddingStart="16dp"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5dp" android:src="@drawable/fb" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5dp" android:src="@drawable/fb" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5dp" android:src="@drawable/fb" /> </LinearLayout> <TextView android:id="@+id/text_dashboard_version" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="end" android:layout_marginTop="25dp" android:paddingBottom="5dp" android:paddingEnd="16dp" android:paddingRight="16dp" android:text="Version 1.0" /> </LinearLayout> </android.support.design.widget.NavigationView> </LinearLayout> </RelativeLayout> </android.support.v4.widget.NestedScrollView> </android.support.design.widget.NavigationView>


Debe tener un diseño de vista de navegación de contenedor y luego debe contener dos diseños de navegación más. Los alinea con la parte superior e inferior del diseño principal.

Recomendaría usar una vista de navegación como padre y no un FrameLayout porque es esencialmente un ScrimFrameLayout e interactúa mejor con la barra de estado.

Aquí hay un ejemplo de cómo debería ser su actividad:

<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/layout_dashboard" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:context=".MainActivity"> <!-- Activity content goes here --> <android.support.design.widget.NavigationView android:id="@+id/navigation_drawer_container" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start"> <android.support.design.widget.NavigationView android:id="@+id/navigation_drawer" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="top" app:menu="@menu/menu_navigation_drawer" /> <android.support.design.widget.NavigationView android:id="@+id/navigation_drawer_bottom" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom" app:menu="@menu/menu_navigation_drawer_bottom" /> </android.support.design.widget.NavigationView>

Puede leer más al respecto y ver un ejemplo aquí: http://blog.nitish.io/post/122633295558/android-design-library-navigationview-with-top


Es un fastidio que NavigationView no tenga una disposición para agregar pie de página. Pero puedes intentar algo como esto,

<?xml version="1.0" encoding="utf-8"?> <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/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:openDrawer="start"> <include layout="@layout/app_bar_base" android:layout_width="match_parent" android:layout_height="match_parent" /> <android.support.design.widget.NavigationView android:id="@+id/nav_view_container" android:layout_width="wrap_content" android:layout_height="match_parent" android:fitsSystemWindows="false" android:layout_gravity="start" > <android.support.design.widget.NavigationView android:id="@+id/nav_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scrollbarAlwaysDrawVerticalTrack="true" android:scrollbars="vertical" android:isScrollContainer="true" app:headerLayout="@layout/nav_header_base" app:menu="@menu/activity_base_drawer" android:layout_gravity="top" android:layout_marginBottom="x" /> <android.support.design.widget.NavigationView android:id="@+id/nav_view_footer" android:layout_width="wrap_content" android:layout_height="x" app:headerLayout="@layout/hear_layout" app:menu="@menu/menu_items" android:scrollbars="none" android:layout_gravity="bottom" /> </android.support.design.widget.NavigationView> </android.support.v4.widget.DrawerLayout>

En caso de que su pie de página sea una lista,

app:headerLayout="@null" app:menu="@menu/activity_base_drawer_footer"

Pero, si es algún tipo de vista personalizada,

app:headerLayout="@layout/my_cutom_footer_view" app:menu="@null"

Además, en este caso, deberá establecer x = height of your custom footer view

Espero eso ayude.


Hice lo mismo de la siguiente manera

<include layout="@layout/app_bar_main" android:layout_width="match_parent" android:layout_height="match_parent" /> <android.support.design.widget.NavigationView android:id="@+id/nav_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" app:headerLayout="@layout/nav_header_main" app:menu="@menu/activity_main_drawer" > <LinearLayout android:layout_gravity="bottom" android:background="#20191d1e" android:layout_width="match_parent" android:paddingBottom="2dp" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="2dp" android:orientation="horizontal" android:layout_height="wrap_content"> <ImageView android:id="@+id/company_image_id" android:layout_width="50dp" android:layout_height="50dp" android:layout_margin="@dimen/margin1dp" android:padding="@dimen/margin2dp" android:src="@mipmap/ic_launcher_round" /> <TextView android:id="@+id/txtCompanyName" android:layout_width="match_parent" android:layout_marginLeft="@dimen/margin3dp" android:layout_height="wrap_content" android:textSize="13dp" android:layout_gravity="center" android:textStyle="bold" android:textAppearance="@style/TextAppearance.AppCompat.Body1" /> </LinearLayout> </android.support.design.widget.NavigationView> </android.support.v4.widget.DrawerLayout>

Aquí lo principal es que puse la gravedad del diseño en el fondo, por ejemplo

**LinearLayout android:layout_gravity="bottom"**


La estructura de diseño del encabezado y pie de página fijos en el menú del cajón:

<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout> <android.support.design.widget.AppBarLayout> <android.support.v7.widget.Toolbar/> </android.support.design.widget.AppBarLayout> <LinearLayout> <include layout="@layout/drawer_header"/> <android.support.design.widget.NavigationView/> <include layout="@layout/drawer_footer"/> </LinearLayout> </android.support.v4.widget.DrawerLayout>

El diseño completo:

<?xml version="1.0" encoding="utf-8"?> <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:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:openDrawer="start"> <android.support.design.widget.AppBarLayout android:id="@+id/app_bar_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/AppTheme.AppBarOverlay" app:elevation="0dp"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?actionBarSize" app:layout_scrollFlags="scroll|enterAlways" app:popupTheme="@style/AppTheme.PopupOverlay" > </android.support.v7.widget.Toolbar> </android.support.design.widget.AppBarLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/white" android:layout_gravity="start" android:orientation="vertical"> <include layout="@layout/drawer_menu_header"/> <android.support.design.widget.NavigationView android:id="@+id/drawer_menu_body" app:elevation="0dp" android:layout_height="0dp" android:layout_width="match_parent" android:layout_weight="1" android:background="@color/white" android:theme="@style/AppTheme.PopupOverlay" app:menu="@menu/main_drawer"> </android.support.design.widget.NavigationView> <include layout="@layout/drawer_menu_footer"/> </LinearLayout> </android.support.v4.widget.DrawerLayout>


La respuesta más simple es agregar un botón dentro del diseño del cajón y establecer su gravedad en la parte inferior en navigationview.xml .

Aquí está el código:

<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.NavigationView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/navigation" android:layout_width="200dp" android:layout_height="match_parent" android:layout_gravity="start" app:headerLayout="@layout/navigation_header" app:menu="@menu/menu_navigation"> <Button android:id="@+id/btn_sing_in" android:layout_width="match_parent" android:layout_height="50dp" android:text="@string/sign_in" android:layout_gravity="bottom"/> </android.support.design.widget.NavigationView>


Mi solución personal para el encabezado y pie de página fijos es extender NavigationView de la siguiente manera:

/** * Created by guness on 17.01.2018. */ class NavigationView : android.support.design.widget.NavigationView { private var mHeader: View? = null private var mFooter: View? = null private var mMenuView: NavigationMenuView? = null constructor(context: Context) : this(context, null) constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0) constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { val a = TintTypedArray.obtainStyledAttributes(context, attrs, R.styleable.NavigationView, defStyleAttr, R.style.Widget_Design_NavigationView) if (a.hasValue(R.styleable.NavigationView_footerLayout)) { inflateFooterView(a.getResourceId(R.styleable.NavigationView_footerLayout, 0)) } a.recycle() (mFooter?.layoutParams as FrameLayout.LayoutParams?)?.gravity = Gravity.BOTTOM } init { (0 until childCount) .map { getChildAt(it) } .filter { it is NavigationMenuView } .forEach { mMenuView = it as NavigationMenuView mMenuView!!.overScrollMode = View.OVER_SCROLL_NEVER } } override fun inflateHeaderView(@LayoutRes res: Int): View { mHeader = LayoutInflater.from(context).inflate(res, this, false) setHeaderView(mHeader!!) return mHeader!! } @Deprecated("There can only be one header", ReplaceWith("#setHeaderView(view: View)")) override fun addHeaderView(view: View) { throw IllegalAccessException("Please use #setHeaderView") } @UiThread fun setHeaderView(view: View) { removeHeaderView() mHeader = view addView(mHeader, 0) } @Deprecated("No need to use params", ReplaceWith("#removeHeaderView()")) override fun removeHeaderView(view: View) { removeHeaderView() } @UiThread fun removeHeaderView() { if (mHeader != null) { removeView(mHeader) mHeader = null } } @Deprecated("No need to count, it is either 1 or zero", ReplaceWith("#hasHeader()")) override fun getHeaderCount(): Int { return if (mHeader == null) 0 else 1 } @Deprecated("No need to use params", ReplaceWith("#getHeaderView()")) override fun getHeaderView(index: Int): View? { return getHeaderView() } fun getHeaderView(): View? { return mHeader } fun hasHeader(): Boolean { return mHeader != null } fun inflateFooterView(@LayoutRes res: Int): View { mFooter = LayoutInflater.from(context).inflate(res, this, false) setFooterView(mFooter!!) return mFooter!! } @UiThread fun setFooterView(view: View) { removeFooterView() mFooter = view addView(mFooter, 0) } @UiThread fun removeFooterView() { if (mFooter != null) { removeView(mFooter) mFooter = null } } fun hasFooter(): Boolean { return mFooter != null } fun getFooterView(): View? { return mFooter } fun setOnClickListener(@IdRes res: Int, listener: View.OnClickListener) { mHeader?.findViewById<View>(res)?.setOnClickListener(listener) mFooter?.findViewById<View>(res)?.setOnClickListener(listener) } override fun onMeasure(widthSpec: Int, heightSpec: Int) { super.onMeasure(widthSpec, heightSpec) val headerHeight = mHeader?.measuredHeight ?: 0 val footerHeight = mFooter?.measuredHeight ?: 0 val params = (mMenuView?.layoutParams as ViewGroup.MarginLayoutParams?) var changed = false if (params?.topMargin != headerHeight) { params?.topMargin = headerHeight changed = true } if (params?.bottomMargin != footerHeight) { params?.bottomMargin = footerHeight changed = true } if (changed) { mMenuView!!.measure(widthSpec, heightSpec) } } }

Originalmente NavigationView crea un diseño lineal como primer elemento en RecyclerView y desplaza todo el contenido. La idea sobre esto es crear vistas separadas para el pie de página y el encabezado y luego, empujarlas hacia arriba y hacia abajo usando Gravity. Más adelante, la medición de contenido para RecyclerView establece el contenido de desplazamiento.

Aquí está la biblioteca que contiene el código anterior que escribí. https://github.com/guness/NavigationView

Un buen lado de esto, ahora puedo definir la vista de pie de página en el xml al igual que el encabezado en nativo:

app:footerLayout="@layout/nav_footer_main" app:headerLayout="@layout/nav_header_main"


Prueba esto, este trabajo para mí. https://github.com/MarcDahlem/AndroidSidemenuFooterExample/blob/master/app/src/main/res/layout/activity_main.xml

Sin embargo, debe deshabilitar NavigationViewScrolling para un desplazamiento más suave

private void disableNavigationViewScrolling(NavigationView navigationView) { if (navigationView != null) { NavigationMenuView navigationMenuView = (NavigationMenuView) navigationView.getChildAt(0); if (navigationMenuView != null) { navigationMenuView.setNestedScrollingEnabled(false); } } }

Screenshots:


Prueba esto, este trabajo para mí.

<android.support.design.widget.NavigationView android:id="@+id/nav_view1" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true"> <ScrollView android:layout_width="wrap_content" android:layout_height="match_parent"> <LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:orientation="vertical"> <android.support.design.widget.NavigationView android:layout_width="wrap_content" android:layout_height="match_parent" android:id="@+id/nav_view" app:headerLayout="@layout/nav_header_admin" app:menu="@menu/activity_admin_drawer"/> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:id="@+id/lyNavFooter"> <!--INCLUDE YOUR FOOTER HERE --> </LinearLayout> </LinearLayout> </ScrollView> </android.support.design.widget.NavigationView>


Sé que es una respuesta tardía, pero es la respuesta perfecta y precisa que buscan la mayoría de los desarrolladores.

Para agregar pie de página en la vista de navegación, agregue una vista personalizada en el menú de navegación como se muestra a continuación:

footer_navigation_menu.xml

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <android.support.v7.widget.AppCompatTextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:text="@string/version" /> <android.support.v7.widget.AppCompatTextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:gravity="right" /> </RelativeLayout>

Ahora, agregue la vista anterior en su menú xml con el atributo de grupo, de modo que pueda diferenciarse como pie de página en el menú.

profile_menu.xml

<group android:checkableBehavior="single"> <item android:id="@+id/nav_support" android:title="@string/nav_item_support" /> <item android:id="@+id/nav_settings" android:title="@string/nav_item_settings" /> <item android:id="@+id/nav_log_out" android:title="@string/nav_item_log_out" /> </group> <group android:id="@+id/nav_footer"> <item android:id="@+id/nav_log_version" app:actionLayout="@layout/footer_navigation_menu" /> </group>

Eso es. A continuación se muestra la salida:


Si desea un pie de página fijo (sin desplazamiento) en su menú de navegación, necesita ajustar NavigationView alrededor de otro diseño, como lo ha publicado. NavigationView funciona como FrameLayout, por lo que esto termina "apilando" el diseño interno en la parte superior de los elementos del menú NavigationView. Aquí hay una forma de organizarlo, usando LinearLayout para los elementos de pie de página:

Pie de página fijo

<android.support.design.widget.NavigationView android:id="@+id/drawer" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" app:headerLayout="@layout/drawer_header" app:menu="@menu/drawer"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:clickable="true" android:orientation="vertical"> <TextView android:id="@+id/footer_item_1" android:layout_width="match_parent" android:layout_height="48dp" android:gravity="center" android:text="Footer Item 1" /> <TextView android:id="@+id/footer_item_2" android:layout_width="match_parent" android:layout_height="48dp" android:gravity="center" android:text="Footer Item 2" /> </LinearLayout> </android.support.design.widget.NavigationView>

Utilicé TextViews en este ejemplo, pero puedes usar lo que quieras para las vistas de pie de página. Para evitar que los elementos del pie de página se superpongan con la parte inferior del menú, agregue algunos elementos ficticios al final del archivo de recursos del menú (estos actuarán como "espaciadores"):

res / menu / drawer.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"> <group> <item android:id="@+id/nav_item_1" android:icon="@drawable/ic_nav_item_1" android:title="Nav Item 1" /> <item android:id="@+id/nav_item_2" android:icon="@drawable/ic_nav_item_2" android:title="Nav Item 2" /> <item android:id="@+id/nav_item_3" android:icon="@drawable/ic_nav_item_3" android:title="Nav Item 3" /> <item android:id="@+id/nav_item_4" android:icon="@drawable/ic_nav_item_4" android:title="Nav Item 4" /> <item android:id="@+id/footer_spacer_1" android:checkable="false" android:enabled="false" android:orderInCategory="200" android:title="" /> <item android:id="@+id/footer_spacer_2" android:checkable="false" android:enabled="false" android:orderInCategory="200" android:title="" /> </group> </menu>

Por último, no olvide agregar oyentes de clics en su Actividad para las vistas reales del pie de página:

... // Click listener for nav footer. View navFooter1 = findViewById(R.id.footer_item_1); navFooter1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Do footer action } }); View navFooter2 = findViewById(R.id.footer_item_2); navFooter2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Do footer action } }); ...

Pie de página desplazable

Sin embargo, si permite que el pie de página se desplace con el resto de NavigationView, esto simplifica las cosas (sin diseños adicionales ni escuchas de clics). Simplemente agregue los elementos de pie de página a su archivo de recursos de menú como un <group> único (esto creará una línea de separación ), y todo se manejará automáticamente y se desplazará junto:

res / menu / drawer.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"> <group android:id="@+id/nav_menu"> <item android:id="@+id/nav_item_1" android:icon="@drawable/ic_nav_item_1" android:title="Nav Item 1" /> <item android:id="@+id/nav_item_2" android:icon="@drawable/ic_nav_item_2" android:title="Nav Item 2" /> <item android:id="@+id/nav_item_3" android:icon="@drawable/ic_nav_item_3" android:title="Nav Item 3" /> <item android:id="@+id/nav_item_4" android:icon="@drawable/ic_nav_item_4" android:title="Nav Item 4" /> </group> <group android:id="@+id/nav_footer"> <item android:id="@+id/nav_footer_1" android:icon="@drawable/ic_footer_item_1" android:title="Footer Item 1" /> <item android:id="@+id/nav_footer_2" android:icon="@drawable/ic_footer_item_2" android:title="Footer Item 2" /> </group> </menu>


Siguiendo los enfoques descritos en las otras respuestas de vistas de navegación anidadas, surgieron algunos problemas:

  • Con muchos elementos, o en modo horizontal, el pie de página se superpone con los elementos del menú
  • Si el menú real tiene muchos elementos, el NavigationView anidado se puede desplazar, lo que no se veía bien
  • Tener dos NavigationViews en el anidamiento no permitía definir vistas personalizadas como pie de página.
  • El manejo de las vistas de desplazamiento anidadas fue un desastre (a veces aparecían dos barras de desplazamiento, etc.)
  • El pie de página fijo siempre debe estar en la parte inferior (con pocos y muchos elementos de menú)

Mi solución para todos estos problemas fue la siguiente:

<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout ...> <include layout="@layout/main_content"/> <android.support.design.widget.NavigationView ...> <android.support.v4.widget.NestedScrollView ... android:fillViewport="true" android:scrollbars="vertical"> <LinearLayout ... android:orientation="vertical"> <android.support.design.widget.NavigationView ... app:elevation="0dp" app:headerLayout="@layout/nav_header" app:menu="@menu/nav_menu"> </android.support.design.widget.NavigationView> <LinearLayout android:id="@+id/spacer_to_bottom" ... android:layout_height="0dp" android:layout_weight="1"> </LinearLayout> <include layout="@layout/nav_footer"></include> </LinearLayout> </android.support.v4.widget.NestedScrollView> </android.support.design.widget.NavigationView> </android.support.v4.widget.DrawerLayout>

Aquí, el NestedScrollView actúa como un padre de desplazamiento para el sub-NavigationView. Eso significa que el Sub-NavigationView nunca muestra barras de desplazamiento en sí, pero todo el contenido se muestra de manera plana.

El diseño ''spacer_to_bottom'' llena todo el espacio restante, de modo que con pocos iconos de menú, el pie de página todavía está en la parte inferior.

Finalmente, el pie de página fijo se agrega al diseño lineal, que comienza con el menú real (sub-NavigationView), el espaciador, y tiene en la parte inferior el pie de página.

Aquí puede encontrar el ejemplo de trabajo completo como AndroidStudio-Project: https://github.com/MarcDahlem/AndroidSidemenuFooterExample

Especialmente el cajón de navegación se puede encontrar aquí: https://github.com/MarcDahlem/AndroidSidemenuFooterExample/blob/master/app/src/main/res/layout/activity_main.xml

Capturas de pantalla


Siguiendo su enfoque, algunos cambios menores pueden ayudar a lo que desea lograr.

<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:background="@color/background_material_light"> <TextView android:id="@+id/footer_item" android:layout_width="match_parent" android:layout_height="?attr/listPreferredItemHeight" android:background="?attr/selectableItemBackground" android:gravity="center_vertical" android:paddingLeft="?attr/listPreferredItemPaddingLeft" android:text="Something" android:textAppearance="?attr/textAppearanceListItem" /> </LinearLayout>

Y configure algunos elementos de código auxiliar en el menú, para que los elementos del menú no se superpongan.

<group> ... <item android:title="" android:orderInCategory="200"/> </group>

También querrá agregar un escucha de clics a su elemento de pie de página.


Simplemente coloque otro diseño dentro de su NavigationView:

<android.support.design.widget.NavigationView android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:background="#000000" app:itemTextColor="#FFFFFF" app:headerLayout="@layout/fragment_side_menu_header" app:menu="@menu/side_menu"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:layout_gravity="bottom"> <TextView android:textColor="#FFFFFF" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="test" /> <TextView android:textColor="#FFFFFF" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="test2" /> </LinearLayout> </android.support.design.widget.NavigationView>

El truco es usar layout_gravity = "bottom": esto colocará todo el diseño en la parte inferior y probará, test2 está correctamente apilado.


Solo te daré una pista sobre cómo resolverlo, pero no tengo oportunidad de probarlo en NavigationView, y estoy bastante seguro de que funcionará

aquí el diseño de muestra xml;

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:clipToPadding="false" android:paddingBottom="96dp"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:background="#6F00" /> <TextView android:layout_width="match_parent" android:layout_height="96dp" android:layout_gravity="bottom" android:layout_marginBottom="-96dp" android:background="#600F" /> </FrameLayout>

Aquí está el resultado:

El truco consiste en aplicar el relleno al padre y el margen negativo al niño.

Prueba rápida:

<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.NavigationView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="start" android:clipToPadding="false" android:paddingBottom="96dp" app:headerLayout="@layout/sample_header" app:menu="@menu/sample_menu"> <TextView android:layout_width="match_parent" android:layout_height="96dp" android:layout_gravity="bottom" android:layout_marginBottom="-96dp" android:background="#600F" android:gravity="center" android:text="I STAND BY MY SELF" /> </android.support.design.widget.NavigationView>


Yo uso este formulario, trabaja para mí. en paisaje y retrato.

<android.support.design.widget.NavigationView android:id="@+id/nav_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start"> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.design.widget.NavigationView android:id="@+id/navigation" android:layout_width="wrap_content" android:layout_height="0dp" android:layout_weight="1" app:headerLayout="@layout/master_main_header" app:itemIconTint="@color/blue" app:menu="@menu/menu_drawer"> </android.support.design.widget.NavigationView> <Button android:id="@+id/master_btn_closession" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="0" android:background="@color/blue" android:text="Cerrar sesión" /> </LinearLayout> </android.support.design.widget.NavigationView>


utilizar este..

<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="@color/accent" app:itemTextColor="@color/primary_text" app:menu="@menu/navigation_drawer_items"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:background="@color/grey_200" android:orientation="vertical"> <View android:layout_width="match_parent" android:layout_height="@dimen/divider_height" android:background="@color/grey_600"/> <com.facebook.share.widget.LikeView android:id="@+id/like_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="start" android:padding="@dimen/small"/> <com.facebook.login.widget.LoginButton android:id="@+id/login_button" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="@dimen/small"/> </LinearLayout> </android.support.design.widget.NavigationView>

luego establezca el relleno inferior en NavigationMenuView

final View menuView = navigationView.getChildAt(0); final View bottomView = navigationView.getChildAt(1); bottomView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { menuView.setPadding(0, 0, 0, bottomView.getMeasuredHeight()); } });


<include layout="@layout/app_bar_main" android:layout_width="match_parent" android:layout_height="match_parent" /> <android.support.design.widget.NavigationView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true" app:menu="@menu/activity_main_drawer"> <android.support.v4.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true" android:scrollbars="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <android.support.design.widget.NavigationView android:id="@+id/nav_view" android:layout_width="match_parent" android:layout_height="wrap_content" app:elevation="0dp" app:headerLayout="@layout/nav_header_main" app:menu="@menu/activity_main_drawer"> ></android.support.design.widget.NavigationView> <LinearLayout android:id="@+id/spacer_to_bottom" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:orientation="vertical" /> </LinearLayout> </android.support.v4.widget.NestedScrollView> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:layout_marginBottom="0dp"> <include layout="@layout/nav_footer_main" /> </LinearLayout> </android.support.design.widget.NavigationView>


NavigationView primer elemento secundario NavigationView es el ListView contiene elementos de encabezado y menú.

Lo único que se necesita para agregar un pie de página es llamar a .addFooterView a ListView

Más información: http://www.andreabaccega.com/blog/2015/08/28/how-to-add-footer-to-navigationview/

Copiar código de pegar:

public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); ListView listView = (ListView) navigationView.getChildAt(0); View toRet = LayoutInflater.from(view.getContext()).inflate(R.layout.drawer_footer, listView, false); // Manipulate the view (if you need to) before calling addFooterView. listView.addFooterView(toRet, null, false); }


Mi solución con pie de página fijo y menús de desplazamiento (100% probado)

<android.support.design.widget.NavigationView android:id="@+id/container_navigation" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="" android:nestedScrollingEnabled="true" android:scrollIndicators="none"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.design.widget.NavigationView android:id="@+id/navigation" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_above="@+id/navigation2" android:layout_gravity="top" android:nestedScrollingEnabled="true" android:paddingBottom="@dimen/dimen_20_dp" app:headerLayout="@layout/nav_header" app:itemIconTint="@color/black_800" app:itemTextColor="@color/black_800" app:menu="@menu/navigation_drawer_items"> </android.support.design.widget.NavigationView> <android.support.design.widget.NavigationView android:id="@+id/navigation2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:background="@color/white_100" android:orientation="horizontal"> <TextView android:id="@+id/empty_spacer" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:drawableTop="@drawable/ic_search" android:gravity="center" android:text="Share" /> <TextView android:id="@+id/mnuRate" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:drawableTop="@drawable/ic_search" android:gravity="center" android:text="Rate" /> <TextView android:id="@+id/mnuHelp" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:drawableTop="@drawable/ic_search" android:gravity="center" android:text="Help" /> </LinearLayout> </android.support.design.widget.NavigationView> </RelativeLayout> </android.support.design.widget.NavigationView>


Pie de página desplazable para la versión> 23.xx

Finalmente logré lo que quería, desafortunadamente parece que ya no es posible simplemente tomar la referencia a ListView y agregar un encabezado y pie de página como en las versiones debajo de 23.xx (como lo describe Andrea Baccega). Hacer esto para el encabezado todavía es posible:

<android.support.design.widget.NavigationView .. app:headerLayout="@layout/item_drawer_footer" .. />

Pero agregar un pie de página no es posible en este momento. Sin embargo, encontré una solución alternativa en caso de que solo intente agregar un pie de página: simplemente invierte la vista, esto agregará el encabezado en la parte inferior que se comporta como un pie de página normal. Solo asegúrate de crear tu menú en orden inverso

// Grab reference to the embedded recycler view RecyclerView mRecyclerView = (RecyclerView) navigationView.getChildAt(0); // Create a LinearLayoutManager and set it to reversed LinearLayoutManager mLayoutManager = new LinearLayoutManager(this); mLayoutManager.setReverseLayout(true); // Apply layout manager to the recycler view mRecyclerView.setLayoutManager(mLayoutManager);