¿Cómo agregar pie de página a NavigationView – biblioteca de diseño de soporte de Android?

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

Esto no se desplaza en pantallas pequeñas:

    

NO DESPLAZAMIENTO

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

    

enter image description here

Drawer menu res/menu/drawer.xml file:

          

Si desea un pie de página fijo (sin desplazamiento) en su menú de navegación, debe ajustar NavigationView alrededor de otro diseño, como el que ha publicado. NavigationView funciona como FrameLayout, por lo que termina “astackndo” el diseño interno en la parte superior de los elementos del menú NavigationView. Esta es una forma de organizarlo, utilizando LinearLayout para los artículos del pie de página:

Pie de página fijo

       

Usé TextViews en este ejemplo, pero puede usar lo que quiera 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 de su archivo de recursos del menú (estos actuarán como “espaciadores”):

res / menu / drawer.xml

           

Por último, no olvide agregar escuchas de clic en su Actividad para las vistas actuales 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 } }); ... 

Desplazamiento de pie de página

Sin embargo, si permite que el pie de página se desplace con el rest del NavigationView, simplificará las cosas (sin diseños adicionales ni escuchas de clic). Simplemente agregue los elementos del pie de página al archivo de recursos del menú como un único (esto creará una línea separadora ), y todo se manejará automáticamente y se desplazarán juntos:

res / menu / drawer.xml

             

Te daré la pista de cómo solucionarlo, pero no tengo la oportunidad de probarlo en NavigationView, y estoy bastante seguro de que funcionará

aquí el diseño de muestra xml;

     

aquí está el resultado:

enter image description here

el truco es aplicar relleno al padre y menos margen al niño.


Prueba rápida:

     

enter image description here

Siguiendo los enfoques descritos en las otras respuestas de las vistas de navegación de anidación, 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, NavigationView nested tiene desplazamiento, lo que no se veía bien
  • Tener dos NavigationViews en el nested, no permitió definir vistas personalizadas como pie de página.
  • El manejo de scrollviews nesteds era 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 con muchos elementos de menú)

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

                

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

El diseño ‘spacer_to_bottom’ llena todo el espacio restante, de modo que con pocos icons de menú, el pie de página sigue estando 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 completo de trabajo 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:

Pocos artículos Muchos artículos

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 el navigationview.xml .

Aquí está el código:

     

aquí está el resultado

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

Yo recomendaría usar una vista de navegación como padre y no 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:

       

Puedes leer más sobre él y ver un ejemplo aquí: http://blog.nitish.io/post/122633295558/android-design-library-navigationview-with-top

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

         

En caso de que si su pie de página es 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.

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

    

Y establezca algunos elementos de stub en el menú, para que los elementos del menú no se superpongan.

  ...   

También desearía agregar un oyente de clic a su elemento de pie de página.

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

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

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

Copia y pega el código:

 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 un pie de página fijo y menús de desplazamiento (100% probado)

               

Simplemente coloque otro diseño dentro de su NavigationView:

       

El truco es usar layout_gravity = “bottom”: esto colocará todo el diseño en la parte inferior y test, test2 se astackrá correctamente.

utilizar esta..

        

luego configure 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()); } }); 

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

        

Prueba esto, este trabajo para mí.

           

      >        

Esto me funciona para poner las imágenes al pie del cajón de navegación (retrato y orientación horizontal)

         >        

mi nav_footer_main3 es

      

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

                      

La estructura de disposición para el encabezado y pie de página adhesivo en el menú del cajón:

            

El diseño completo:

              

Desplazamiento del pie de página para Versión> 23.xx

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

   

Pero agregar un pie de página no es posible en este momento. Sin embargo, encontré una solución alternativa en caso de que esté tratando de agregar un pie de página: simplemente invierte la vista, esto agregará el encabezado al pie 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); 

Mi solución personal para encabezado fijo y pie de página 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(res)?.setOnClickListener(listener) mFooter?.findViewById(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 LinearLayout como primer elemento en el RecyclerView y se desplaza todo el contenido juntos. La idea al respecto es crear vistas separadas para el pie de página y el encabezado y luego, empujarlas hacia arriba y abajo usando Gravedad. Más tarde, la medición del contenido de RecyclerView establece el contenido de desplazamiento.

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

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, puede desactivar 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); } } } 

Capturas de pantalla:

 I made the same thing in the following manner           Here the main thing is that i put the layout gravity to bottom eg **LinearLayout android:layout_gravity="bottom"** [![enter image description here][1]][1]