Jak dodać stopkę do NavigationView - biblioteki projektów obsługi Androida?


122

Jak mogę ustawić ustawienia stopki i elementy profilu na NavitationView? wygląda jak szuflada nawigacji w skrzynce odbiorczej. Te NavitationViewelementy są zawyżone przez menu zasobu, ale nie wiem jak ustawić dolne pozycje menu do zasobu, lub w jaki sposób mogę ustawić niestandardowy widok na NavigationViewlub dno offset? Próbowałem umieścić to <LinearLayout...>jako widok stopki, ale na małych ekranach stopka umieszcza elementy i nie mogę przewijać menu, próbowałem ustawić dopełnienie stopki na NavigationView, ale stopka też ją przyjmuje.

To nie jest przewijanie na małych ekranach:

<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>

NIE PRZEWIJANIE

To się przewija, ale stopka znajduje się nad pozycjami menu:

<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>

wprowadź opis obrazu tutaj

res/menu/drawer.xmlPlik menu szuflady :

<?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>

W której lokalizacji umieściłeś plik @ menu / szuflady ...
Psypher

To właśnie w/res/menu/drawer.xml
epool

Czy jest jakiś powód, dla którego nie możesz użyć opcji „Opinia” i „Wyloguj się” jako pozycji menu? Jeśli powodem jest to, że chcesz dynamicznie zmieniać ikonę menu „Wyloguj się”, powinieneś być w stanie to zrobić za pomocą menuItem.setIcon(Drawable).
Hungryghost

To tylko dla wymagań i osobiście chcę wiedzieć, jak Google robi to na przykład w aplikacji skrzynki odbiorczej.
epool

To pytanie staje się jeszcze ważniejsze po aktualizacji 23.1
Alex Sorokoletov

Odpowiedzi:


151

Jeśli chcesz mieć stałą (nie przewijaną) stopkę w menu nawigacyjnym, musisz zawinąć NavigationView wokół innego układu, tak jak opublikowałeś. NavigationView działa podobnie jak FrameLayout, więc kończy się to „układaniem” wewnętrznego układu na górze elementów menu NavigationView. Oto jeden sposób, aby to zorganizować, używając LinearLayout dla elementów stopki:

Naprawiono stopkę

<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>

W tym przykładzie użyłem TextViews, ale w widokach stopki możesz użyć wszystkiego, co chcesz. Aby elementy stopki nie pokrywały się z dolną częścią menu, dodaj kilka fikcyjnych elementów na końcu pliku zasobów menu (będą one działać jak „odstępniki”):

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>

Na koniec nie zapomnij dodać odbiorników kliknięć w swoim działaniu, aby uzyskać faktyczne widoki stopki:

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

Przewijana stopka

Jeśli jednak pozwolisz stopce na przewijanie z resztą NavigationView, upraszcza to (bez dodatkowych układów ani detektorów kliknięć). Po prostu dodaj elementy stopki do pliku zasobów menu jako unikalne <group>(spowoduje to utworzenie linii separatora ), a wszystko będzie obsługiwane automatycznie i przewijane razem:

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>

1
To tylko dla wymagań i osobiście chcę wiedzieć, jak Google robi to na przykład w aplikacji skrzynki odbiorczej.
epool

Nie jestem pewien, jak Google to robi w aplikacji Gmail, ale z pozoru wygląda to tak, jak opisałem w odpowiedzi. Użyj osobnego, <group> jeśli chcesz mieć linię separatora, w przeciwnym razie stopka nawigacyjna aplikacji Gmail wygląda jak zwykłe pozycje menu (przynajmniej dla mnie).
Hungryghost

1
Ahh, teraz rozumiem. Wydawało mi się, że mówisz o aplikacji Gmail. Nie zainstalowałem aplikacji skrzynki odbiorczej, ale jeśli szukasz statycznej stopki, to masz rację, musisz użyć osobnego układu. To nie powinno być jednak zbyt trudne. Zobaczmy ...
hungryghost

7
możesz użyć <dimen name="design_navigation_padding_bottom" tools:override="true">48dp</dimen> w dimen.xmlzamiast używać fikcyjnych pozycji w menu! jest doskonały!
Omid

1
Jak ustawić czcionkę elementu szuflady i rozmiar czcionki dla widoku tekstu stopki?
JEGADEESAN S

37

Podam ci tylko podpowiedź, jak to rozwiązać, ale nie mam szans przetestować tego na NavigationView i jestem prawie pewien, że zadziała

tutaj przykładowy układ 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>

oto wynik:

wprowadź opis obrazu tutaj

sztuczka polega na zastosowaniu dopełnienia do rodzica i minus margines do dziecka.


Szybka próba:

<?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>

wprowadź opis obrazu tutaj


3
To może zadziałać, ale ujemne marże są dość hakerskie. Więc osobiście unikam ich, jeśli to możliwe.
Hungryghost

Ta stopka, jeśli umieścisz ikony wyśrodkowane "botom", możesz zmienić w zależności od ekranu i zostanie przycięta zobacz ten post stackoverflow.com/questions/32460312/ ...

Czy możesz podać link do pełnego przykładu?

czy możemy ustawić to jako przewijalne?
Ahmad Shahwaiz

27

Zgodnie z podejściami opisanymi w innych odpowiedziach dotyczących zagnieżdżania widoków nawigacji, pojawiły się pewne problemy:

  • W przypadku wielu elementów lub w trybie poziomym stopka nakładała się na elementy menu
  • Jeśli rzeczywiste menu zawiera wiele elementów, zagnieżdżony NavigationView był przewijany, co nie wyglądało ładnie
  • Posiadanie dwóch NavigationViews w zagnieżdżeniu, nie pozwalało na definiowanie niestandardowych widoków jako stopki.
  • Obsługa zagnieżdżonych widoków przewijania była bałaganem (czasami pojawiały się dwa paski przewijania itp.)
  • Stała stopka powinna zawsze znajdować się na dole (zarówno z kilkoma, jak iz wieloma elementami menu)

Moje rozwiązanie wszystkich tych problemów było następujące:

<?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>

W tym miejscu NestedScrollView działa jako przewijany element nadrzędny dla sub-NavigationView. Oznacza to, że sub-NavigationView nigdy nie wyświetla samych pasków przewijania, ale cała zawartość jest wyświetlana w sposób płaski.

Układ „spacer_to_bottom” wypełnia całą pozostałą przestrzeń, więc przy kilku ikonach menu stopka nadal znajduje się na dole.

Na koniec stała stopka jest dodawana do układu liniowego, który zaczyna się od rzeczywistego menu (sub-NavigationView), odstępnika, a na dole ma stopkę.

Tutaj możesz znaleźć kompletny przykład roboczy jako AndroidStudio-Project: https://github.com/MarcDahlem/AndroidSidemenuFooterExample

Szczególnie szufladę nawigacji można znaleźć tutaj: https://github.com/MarcDahlem/AndroidSidemenuFooterExample/blob/master/app/src/main/res/layout/activity_main.xml

Zrzuty ekranu:

Kilka elementów Wiele przedmiotów


Co dokładnie nie działa? W razie potrzeby mogę podać przykładowy projekt, który świetnie sprawdza się z przewijaną stopką. @AndreaBaccega
Adreamus

Zgadzam się z @AndreaBaccega, nie działa, pokazuje tylko menu nawigacyjne i nie pokazuje stopki
RdlP

ok, drugi z problemami. Utworzę przykładowy projekt i załaduję go na github. wkrótce
Adreamus

Dodałem przykładowy projekt na github: github.com/MarcDahlem/AndroidSidemenuFooterExample
Adreamus

Duży głos za atrybutem wysokości. Szedłem z tym samym podejściem, ale nie mogłem pozbyć się dolnego cienia. Potem znalazłem to. Dziękuję Ci!
Elvedin Selimoski

23

Najprostszą odpowiedzią jest dodanie przycisku w układzie szuflady i ustawienie grawitacji na dole w navigationview.xml.

Oto kod:

<?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>

oto wynik


2
W przypadku kilku pozycji menu może to zadziałać. Ale gdy masz wiele pozycji menu, przycisk będzie się nakładał na pozycje menu na małych urządzeniach lub w trybie poziomym.
Adreamus,

1
prawda, jednak aby temu zaradzić, możesz umieścić puste pozycje menu.
Mohammed Fadhl

wyrównanie dołu z pustymi elementami menu dla różnych rozmiarów ekranu jest prawie możliwe. Ale jest na to ogólny sposób, jak opisałem w moim rozwiązaniu ;-) -> zobacz moje rozwiązanie stackoverflow.com/a/37714353/1075072
Adreamus

17

Musisz mieć układ widoku nawigacji kontenera, który powinien zawierać dwa dodatkowe układy nawigacji. Wyrównaj je do góry i do dołu układu nadrzędnego.

Zalecałbym używanie widoku nawigacji jako elementu nadrzędnego, a nie FrameLayout, ponieważ zasadniczo jest to ScrimFrameLayout i lepiej współdziała z paskiem stanu.

Oto przykład tego, jak powinna wyglądać Twoja aktywność:

<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>

Możesz przeczytać więcej na ten temat i zobaczyć przykład tutaj: http://blog.nitish.io/post/122633295558/android-design-library-navigationview-with-top


1
To naprawdę fajne rozwiązanie. Ale zawijanie zawartości nie działa w NavigationView na górze i na dole. Musisz podać stałą wysokość, aby zapobiec dolnemu blokowi NavigationView górnemu NavigationView.
Olcay Ertaş

idealne rozwiązanie
Bolein95

@Nitaj, jak uniknąć nakładania się, gdy „@ + id / navigation_drawer” ma więcej wartości w trybie portretowym. znalazł się za dolnym widokiem nawigacji. W moim przypadku górne pozycje menu navview są zapełniane dynamicznie, dolne navview mają statyczne wartości menu.
MohanRaj S

14

Znam jego późną odpowiedź, ale jest to doskonała i dokładna odpowiedź, której szuka większość programistów.

Aby dodać stopkę w widoku nawigacji, Dodaj widok niestandardowy do menu nawigacji, tak jak poniżej:

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>

Teraz dodaj powyższy widok do pliku XML menu z atrybutem grupy, aby można go było rozróżnić jako stopkę w menu.

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>

Otóż ​​to. Poniżej jest wyjście:

wprowadź opis obrazu tutaj


Nie będzie działać w przypadku złożonego widoku z dołu, ponieważ zapewnia stałą wysokość widoku z dołu.
Akash Bisariya

To może działać, ale nie ma sposobu, aby ustawić onClickListeners na widoki wewnątrz układu stopki ... W moim przypadku mam przyciski mediów społecznościowych w stopce wysyłające do zewnętrznych adresów URL, ale nie mogłem uzyskać widoków przy użyciu ich identyfikatorów w żaden sposób Mógłbym pomyśleć o ...
Ramiro GM

12

To trochę kłopotliwe, że NavigationView nie ma możliwości dodania stopki. Ale możesz spróbować czegoś takiego,

<?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>

Jeśli Twoja stopka jest listą,

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

Ale jeśli jest to jakiś niestandardowy widok,

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

Również w tym przypadku będziesz musiał ustawić x = height of your custom footer view

Mam nadzieję, że to pomoże.


Dzięki stary. sprawiłeś, że mój dzień ... :)
SiddharthG

3
3 NavigationViews? Czemu? Na najgorsze występy? Obejrzyj niektóre z tych filmów: youtube.com/playlist?list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE
Louis CAD

@LouisCAD Jeśli masz rozwiązanie, które faktycznie działa, bez ujemnego marginesu, podziel się nim z nami. Mam tu wspomniany problem i jest to jedyne rozwiązanie, które biorę pod uwagę. Może nie jest to idealne rozwiązanie i może mieć pewien wpływ na wydajność ... ale bez innej implementacji nie komentuj tylko kwestii wydajności. Przede wszystkim liczą się wymagania dotyczące aplikacji. Jeśli Google nie zapewni rozwiązania spełniającego wymagania Twojej aplikacji ... nie masz wielu opcji.
Dascalescu Vladut

10

wprowadź opis obrazu tutajZrobiłem to samo w następujący sposób:

 <?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_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>

Tutaj najważniejsze jest to, że sprowadziłem grawitację układu do dołu np

LinearLayout android:layout_gravity="bottom"

Dzięki temu rozwiązaniu widok z dołu będzie unosił się nad elementami menu (jeśli jest wiele elementów menu) ... Ale chcę, aby był naprawiony na dole.
Akash Bisariya

7

Zgodnie z twoim podejściem, niektóre drobne zmiany mogą pomóc w tym, co chcesz osiągnąć.

<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>

I ustaw kilka elementów pośredniczących w menu, aby elementy menu się nie nakładały.

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

Chciałbyś również dodać odbiornik kliknięć do elementu stopki.


Dziękuję za odpowiedź. Dzięki temu mogłem obejść problem, aby dodać stopkę, ale mam nadzieję, że zaakceptuję twoją odpowiedź, jeśli nikt nie udzieli mi lepszej odpowiedzi. +1
epool

Miej otwarte opcje. Oczekuję również lepszych odpowiedzi, ponieważ stopki są ważne.
razzledazzle

6

Moje rozwiązanie ze stałą stopką i menu przewijania (przetestowane w 100%)

 <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>

6

W ten sposób mogę dodać układ u dołu nawigacji:

Zaktualizowane biblioteki

    <com.google.android.material.navigation.NavigationView
    android:id="@+id/navigation_drawer_container"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start">

    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

                <com.google.android.material.navigation.NavigationView
                    android:id="@+id/nav_view"
                    android:layout_width="wrap_content"
                    android:layout_height="0dp"
                    android:layout_gravity="top"
                    android:layout_weight="0.8"
                    app:headerLayout="@layout/nav_header_home"
                    app:menu="@menu/activity_home_drawer" />

                <com.google.android.material.navigation.NavigationView
                    android:id="@+id/navigation_drawer_bottom"
                    android:layout_width="wrap_content"
                    android:layout_height="0dp"
                    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>
                </com.google.android.material.navigation.NavigationView>
        </LinearLayout>
    </androidx.core.widget.NestedScrollView>
</com.google.android.material.navigation.NavigationView>

Jest to właściwe rozwiązanie do dodawania układu stopki u dołu widoku nawigacji. Chociaż jeden układ liniowy nie był potrzebny, zredagowałem go w tej odpowiedzi.
Akash Bisariya

Jak ustawiłeś odbiornik wybranego elementu nawigacji w tym działaniu? @zohaib khaliq
Akash Bisariya

5

NavigationView pierwsze dziecko to ListView zawierający zarówno nagłówek, jak i elementy menu.

Jedyną rzeczą potrzebną do dodania stopki jest wywołanie .addFooterView do ListView

Więcej informacji: http://www.andreabaccega.com/blog/2015/08/28/how-to-add-footer-to-navigationview/

Skopiuj wklej kod:

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

10
na „com.android.support:design:23.1.0” nie działa. stał się RecyclerView w NavigationMenuPresenter
gordonpro

Dodałem nową odpowiedź, która może rozwiązać Twój problem.
Lukas

2

Po prostu umieść inny układ w swoim 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>

Sztuczka polega na użyciu layout_gravity = "bottom" - spowoduje to umieszczenie całego układu na dole i sprawdzenie, czy test2 są odpowiednio ułożone.


2

Użyj tego..

<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>

następnie ustaw dopełnienie dolne na 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());
        }
    });

2

Spróbuj tego, to działa dla mnie.

<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>

1

Używam tego formularza, pracuj dla mnie. w poziomie i pionie.

<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>

1

<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>


1
Dodaj wyjaśnienie wraz z odpowiedzią, w jaki sposób ta odpowiedź pomaga OP w naprawianiu bieżącego problemu
ρяσѕρєя K

2
Mam rozwiązanie. Musisz dołączyć statyczny układ stopki, wewnątrz <android.support.design.widget.NavigationView>...</android.support.design.widget.NavigationView>. aby uzyskać więcej informacji, sprawdź repocytorium github ( github.com/mehul0/AndroidSidemenuFooterExample-master )

1

To działa dla mnie, aby umieścić obrazy w stopce szuflady nawigacji (orientacja pionowa i pozioma)

    <?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>

mój nav_footer_main3 to

    <?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>

1

Struktura układu dla lepkiego nagłówka i stopki w menu szuflady:

<?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>

Kompletny układ:

<?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>

1

Spróbuj tego, to działa dla mnie.https://github.com/MarcDahlem/AndroidSidemenuFooterExample/blob/master/app/src/main/res/layout/activity_main.xml

Możesz jednak wyłączyć NavigationViewScrolling, aby przewijać płynniej

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

Zrzuty ekranu:


0

Przewijana stopka dla wersji> 23.xx

W końcu udało mi się osiągnąć to, co chciałem, niestety wygląda na to, że nie da się już po prostu pobrać odniesienia do ListView i dodać nagłówek i stopkę jak w wersjach poniżej 23.xx (jak opisał Andrea Baccega). Robienie tego dla nagłówka jest nadal możliwe:

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

Ale dodanie stopki nie jest obecnie możliwe. Jednak znalazłem obejście na wypadek, gdybyś próbował tylko dodać stopkę: po prostu odwrócisz widok, spowoduje to dodanie nagłówka na dole, który zachowuje się jak normalna stopka. Po prostu utwórz menu w odwrotnej kolejności

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

0

Moje osobiste rozwiązanie dla stałego nagłówka i stopki rozszerza NavigationView w następujący sposób:

/**
 * 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)
    }
}
}

Oryginalnie NavigationView tworzy LinearLayout jako pierwszy element w RecyclerView i przewija całą zawartość razem. Pomysł polega na utworzeniu oddzielnych widoków dla stopki i nagłówka, a następnie przesunięciu ich do góry i do dołu za pomocą Gravity. Później podczas pomiaru zawartości dla RecyclerView ustawia przewijaną zawartość.

Oto biblioteka zawierająca powyższy kod, który napisałem. https://github.com/guness/NavigationView

Dobra strona tego, teraz mogę zdefiniować widok stopki w XML, tak jak nagłówek w natywnym:

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

0

Oto rozwiązanie, które nie wymaga zagnieżdżania i które dynamicznie dostosowuje dolne wypełnienie wewnętrznego NavigationMenuView na podstawie własnej wysokości widoku stopki, co oznacza, że ​​można ustawić wysokość stopki wrap_contenti dynamicznie zmieniać widoczność stopki na VISIBLElub 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);
            }
        }
    }
}

Musisz zdefiniować identyfikator design_navigation_view w swoim ids.xml:

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

I użyj w ten sposób:

    <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>

Testowane z com.google.android.material:material:1.0.0.


0

Jeśli używasz widoku listy, możesz spróbować w ten sposób. Obsługa widoku listy dodaje funkcję widoku stopki, dzięki czemu można dodać niestandardową stopkę widoku R.layout.drawer_footer za pomocą obiektu listview, jak poniżej

View footerView = LayoutInflater.from(getApplicationContext()).inflate(R.layout.drawer_footer, expandableListView, false);
TextView footer = footerView.findViewById(R.id.id_footer_wta_version_information);
expandableListView.addFooterView(footerView);

W moim przypadku używam expandableListView zamiast listview (listview ma również funkcję addFooter). Mam nadzieję, że w ten sposób ci pomogę


-1

Umieść te linie w układzie menu. Mam nadzieję, że to rozwiąże Twój problem:

    <group
        android:id="@+id/grp11"
        android:checkableBehavior="single">

        <item


            android:title="" />
        <item


            android:title="" />
        <item

            android:title="" />
        <item


            android:title="" />
        <item


            android:title="" />
        <item

            android:title="" />

    </group>
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.