Comment append un pied de page à NavigationView – Bibliothèque de conception du support Android?

Comment définir les parameters de pied de page et les éléments de profil sur NavitationView ? to ressemble au tiroir de navigation Inbox by email. Les éléments NavitationView sont gonflés par la ressource de menu, mais je ne sais pas comment définir les éléments inférieurs dans une ressource de menu, ou comment définir une vue personnalisée pour NavigationView ou un décalage inférieur? J’ai essayé de mettre ce en bas de page, mais sur les petits écrans, le pied de page recouvre les éléments et je ne peux pas faire défiler le menu, j’ai essayé de définir un pied de page sur NavigationView , mais le pied de page .

Cela ne fait pas défiler sur les petits écrans:

    

PAS DE DÉFILEMENT

Cela fait défiler, mais le pied de page est sur les éléments du menu:

    

entrer la description de l'image ici

Fichier res/menu/drawer.xml :

          

Si vous voulez un pied de page fixe (sans défilement) dans votre menu de navigation, vous devez envelopper NavigationView autour d’une autre disposition, comme vous l’avez publié. NavigationView fonctionne comme FrameLayout, ce qui finit par “emstackr” la disposition interne par-dessus les éléments du menu NavigationView. Voici un moyen de l’organiser en utilisant LinearLayout pour les éléments de bas de page:

Pied de page fixe

       

J’ai utilisé TextViews dans cet exemple, mais vous pouvez utiliser ce que vous voulez pour les vues de bas de page. Pour éviter que les éléments de bas de page ne se superposent au bas du menu, ajoutez des éléments factices à la fin de votre fichier de ressources de menu (ceux-ci agiront comme des «espaceurs»):

res / menu / drawer.xml

           

Enfin, n’oubliez pas d’append des écouteurs de clics dans votre activité pour les vues de pied de page réelles:

 ... // 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 } }); ... 

Pied de page défilant

Si vous permettez au pied de page de défiler avec le rest de NavigationView, cela simplifie les choses (pas de mise en page supplémentaire ni de clic sur les écouteurs). Ajoutez simplement les éléments de pied de page à votre fichier de ressources de menus en tant que unique (cela créera une ligne de séparation ), et tout sera géré automatiquement et défilera ensemble:

res / menu / drawer.xml

             

Je vais juste vous donner un indice sur la façon de le résoudre, mais je n’ai aucune chance de le tester sur NavigationView, et je suis sûr qu’il fonctionnera

ici la mise en page échantillon xml;

     

voici le résultat:

entrer la description de l'image ici

L’astuce consiste à appliquer un remplissage au parent et à la marge moins à l’enfant.


Essai rapide:

 < ?xml version="1.0" encoding="utf-8"?>    

entrer la description de l'image ici

En suivant les approches décrites dans les autres réponses des vues de navigation d’imbrication, certains problèmes sont apparus:

  • Avec de nombreux éléments, ou en mode paysage, le pied de page se superpose aux éléments du menu.
  • Si le menu réel contient beaucoup d’éléments, la NavigationView nestede a un object défilant
  • Avoir deux NavigationViews dans l’imbrication, ne permettait pas de définir des vues personnalisées en tant que pied de page.
  • Le traitement des scrollviews nesteds était un gâchis (parfois deux barres de défilement apparaissaient, etc.)
  • Le pied de page fixe doit toujours être en bas (avec peu d’articles et avec de nombreux éléments de menu)

Ma solution à tous ces problèmes était la suivante:

 < ?xml version="1.0" encoding="utf-8"?>               

Ici, le NestedScrollView agit en tant que parent défilant pour la sous-navigation Navigation. Cela signifie que la sous-NavigationView ne montre jamais les barres de défilement elle-même, mais que tout le contenu est affiché de manière plate.

La mise en page ‘spacer_to_bottom’ remplit tout l’espace restant, de sorte qu’avec quelques icons de menu, le pied de page est toujours en bas.

Enfin, le pied de page fixe est ajouté à la disposition linéaire, qui commence par le menu réel (sous-NavigationView), l’espaceur et, en bas, le pied de page.

Vous trouverez ici l’exemple complet de travail sous AndroidStudio-Project: https://github.com/MarcDahlem/AndroidSidemenuFooterExample

En particulier le tiroir de navigation peut être trouvé ici: https://github.com/MarcDahlem/AndroidSidemenuFooterExample/blob/master/app/src/main/res/layout/activity_main.xml

Captures d’écran:

Peu d'articles Beaucoup d'articles

La réponse la plus simple consiste à append un bouton dans la disposition du tiroir et à définir la gravité en bas dans navigationview.xml .

Voici le code:

 < ?xml version="1.0" encoding="utf-8"?>    

voici le résultat

Vous devez disposer d’une disposition de vue de navigation de conteneur, qui doit contenir deux autres dispositions de navigation. Vous alignez ceux-ci en haut et en bas de la mise en page parent.

Je recommande d’utiliser une vue de navigation en tant que parent et non en tant que FrameLayout, car il s’agit essentiellement d’un ScrimFrameLayout et interagit mieux avec la barre d’état.

Voici un exemple de ce que devrait être votre activité:

       

Vous pouvez en savoir plus à ce sujet et voir un exemple ici: http://blog.nitish.io/post/122633295558/android-design-library-navigationview-with-top

C’est en quelque sorte un désagrément que NavigationView n’ait pas de disposition pour append un pied de page. Mais vous pouvez essayer quelque chose comme ça,

 < ?xml version="1.0" encoding="utf-8"?>        

Dans le cas où votre pied de page est une liste,

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

Mais, si c’est une sorte de vue personnalisée,

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

De plus, dans ce cas, vous devrez définir x = height of your custom footer view

J’espère que cela aide.

Suivant votre approche, des modifications mineures peuvent vous aider à atteindre vos objectives.

    

Et définissez des éléments de stub dans le menu, de sorte que les éléments de menu ne se chevauchent pas.

  ...   

Vous souhaitez également append un écouteur de clic à votre élément de pied de page.

NavigationView premier enfant de NavigationView est le ListView contenant à la fois l’en-tête et les éléments de menu.

La seule chose nécessaire pour append un pied de page est l’appel .addFooterView à la liste.

Plus d’infos: http://www.andreabaccega.com/blog/2015/08/28/how-to-add-footer-to-navigationview/

Copier le code de collage:

 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); } 

Ma solution avec un pied de page fixe et des menus de défilement (testés à 100%)

               

Placez simplement une autre disposition dans votre NavigationView:

       

L’astuce consiste à utiliser layout_gravity = “bottom” – cela mettra toute votre mise en page en bas et test, les tests2 sont correctement empilés.

utilisez ceci..

        

puis définir le remplissage inférieur à 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()); } }); 

J’utilise ce formulaire, travaille pour moi. en paysage et portrait.

        

Essayez ceci, cela fonctionne pour moi.

           

      >        

Cela fonctionne pour moi pour mettre des images en pied de tiroir de navigation (orientation portrait et paysage)

  < ?xml version="1.0" encoding="utf-8"?>       >        

mon nav_footer_main3 est

  < ?xml version="1.0" encoding="utf-8"?>    

Voici comment je parviens à append une disposition en bas de la navigation:

                      

La structure de mise en page pour l’en-tête et le pied de page dans le menu des tiroirs:

 < ?xml version="1.0" encoding="utf-8"?>           

La mise en page complète:

 < ?xml version="1.0" encoding="utf-8"?>             

Pied de défilement pour la version> 23.xx

J’ai finalement réussi à réaliser ce que je voulais, malheureusement il semble qu’il n’est plus possible de saisir la référence à ListView et d’append un en-tête et un pied de page comme dans les versions inférieures à 23.xx (comme décrit par Andrea Baccega). Faire cela pour l’en-tête est toujours possible:

   

Mais append un pied de page n’est pas possible pour le moment. Cependant, j’ai trouvé une solution de contournement au cas où vous essayiez d’append un pied de page: Vous inversez simplement la vue, cela appenda l’en-tête au bas qui se comporte comme un pied de page normal. Assurez-vous simplement de créer votre menu dans l’ordre inverse

  // 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); 

Ma solution personnelle pour l’en-tête et le pied de page fixe est l’extension de NavigationView comme suit:

 /** * 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: AtsortingbuteSet?) : this(context, attrs, 0) constructor(context: Context, attrs: AtsortingbuteSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { val a = TintTypedArray.obtainStyledAtsortingbutes(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) } } } 

À l’origine, NavigationView crée un object LinearLayout comme premier élément sur RecyclerView et fait défiler tous les contenus. L’idée est de créer des vues séparées pour le pied de page et l’en-tête, puis de les pousser en haut et en bas à l’aide de Gravity. Plus tard, la mesure du contenu pour RecyclerView règle le contenu défilant.

Voici la bibliothèque qui contient le code ci-dessus que j’ai écrit. https://github.com/guness/NavigationView

Bon côté de ceci, maintenant je peux définir la vue de pied de page sur le xml juste comme l’en-tête sur natif:

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

Essayez ceci, cela fonctionne pour moi. https://github.com/MarcDahlem/AndroidSidemenuFooterExample/blob/master/app/src/main/res/layout/activity_main.xml

Cependant, vous devez désactiver NavigationViewScrolling pour un défilement plus fluide.

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

Captures d’écran:

 I made the same thing in the following manner < ?xml version="1.0" encoding="utf-8"?>          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]