Dodanie dolnego marginesu do ostatniego elementu ListView

83

Muszę dodać, aby dodać ListView ze skomplikowanym tłem elementów: różne dla parzystych / nieparzystych i zaokrąglonych rogów na górze i na dole. To wygląda tak:

ListView top

Zaimplementowałem to wszystko za pomocą listy poziomów, ale jest jeszcze jedna rzecz, którą chcę zrobić. Teraz dolny element znajduje się u dołu ekranu. Lepiej jest dodać trochę miejsca.

Dno ListView nie wygląda dobrze

Nie chcę dodawać dolnego marginesu do ListView, potrzebuję marginesu tylko dla ostatniego elementu.

Sposoby, które widzę, aby to zrobić:

Stopka

Coś w rodzaju włamania - dodaj stopkę z pustym TextView do ListView. Ale stopki są dość niestabilne, zwykle znikają po notifyDataSetChanged i nie ma sposobu, aby je odzyskać

Obraz z przezroczystymi pikselami

Poprosiłem projektanta o dodanie przezroczystych pikseli do dolnego zasobu tła. Niestety w tym przypadku centrowanie w pionie jest całkowicie zerwane. Na przykład istnieje 9 łatek takich jak ten:

9patch

I układ taki jak ten:

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

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
        >
    <!-- View with background with transparent pixels on bottom -->
    <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"
                  android:id="@+id/item"
                  android:background="@drawable/some_bgr"
                  android:padding="10dp"
            >
        <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1"
                  android:text="Title"
                  android:layout_gravity="center"
                  android:textSize="18sp"
                />
        <TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
                  android:text="Detail"
                  android:layout_gravity="center"
                  android:textSize="18sp"
                />
    </LinearLayout>

    <!-- Just for marking place took by view -->
    <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent"
                 android:layout_below="@id/item"
                 android:background="#88ff55"
            />
</RelativeLayout>

Wynik:

Wynik

Jak widać, centrowanie nie działa. Niestety. (Przy okazji, jeśli określisz tę 9 poprawkę jako tło dla TextView, wyśrodkowanie działa dobrze. Jeśli znasz jakiś artykuł wyjaśniający to, daj mi znać.)

Dodaj dolny margines do ostatniego elementu w implementacji adaptera

To powinno działać, ale z nieznanego powodu nadal nie mogę sprawić, by zadziałało. Nie podoba mi się ten sposób, ponieważ nie lubię modyfikować wymiarów w kodzie.

Więc

Jest już wyimaginowany sposób - skonstruuj jakiś XML do rysowania z określoną bitmapą i marginesem. Zgodnie z koncepcją drawables powinno to być możliwe, ale nie mogę znaleźć implementacji. Może ktoś wie?

Jakieś inne pomysły?

darja
źródło
chcesz tylko dodać margines po ostatniej pozycji?
Goofy
Tak. Pytanie brzmi dokładnie tak
darja
Proszę sprawdzić moją odpowiedź poniżej
Goofy
Właściwie rozważyłbym użycie podejścia stopki. Nigdy nie widziałem, żeby znikały same, zwłaszcza po telefonie notifyDataSetChanged(). Jeśli tak się dzieje, możesz robić coś innego nie tak. Stopka jest zarządzana przez ListViewi ma niewiele wspólnego z rzeczywistym zbiorem danych adaptera.
MH.
Najlepszym sposobem jest [ stackoverflow.com/questions/6288167/… [1]: stackoverflow.com/questions/6288167/… to naprawdę mi pomogło
Bunyod

Odpowiedzi:

280

W swoim ListViewustaw a paddingBottomi clipToPadding="false".

  <ListView
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:paddingBottom="8dp"
      android:clipToPadding="false"
      android:scrollbarStyle="outsideOverlay"/>
  • Działa to również w przypadku RecyclerView.

  • Używaj tylko android:scrollbarStyle="outsideOverlay"wtedy, gdy chcesz, aby pasek przewijania nie przepełniał obszaru wyściełanego.

zegarmistrz
źródło
moje 8dp od dołu jest obcięte ... właściwie chcę 8dp na dole tylko dla ostatniej pozycji ... więc co robić?
Elizabeth
2
@AndroidBeginner Nie rozumiem, czego chcesz. Dokładnie to robi.
zegarmistrz
12
Nie zapomnij o dodaniu, android:scrollbarStyle="outsideOverlay"aby pasek przewijania nie pozostał wewnątrz wyściółki
gfpacheco
1
mogą wystąpić problemy z kolorami. Dolne wypełnienie ma kolor tła widoku listy, a nie kolor tła ostatniej pozycji
grine4ka
Czy możemy zarządzać wskaźnikiem odświeżania SwipeRefreshLayout przy użyciu tego?
Hemant Kaushik
8

dodaj pustą stopkę do swojej listy w ten sposób:

TextView empty = new TextView(this);
empty.setHeight(150);
listview.addFooterView(empty);
Badr
źródło
w tym celu polecam: listview.addFooterView (puste, dane: null, isSelectable: false);
Simon
4

możesz to też zrobić z kodu jeśli chcesz, na przykład tutaj reaguję na różne sytuacje EditText:

   if(s.toString().length()>0)
   {
      contacts_lv.setClipToPadding(false);
      contacts_lv.setPadding(0,0,0,270*screenDensity);
   }
   else
   {
      contacts_lv.setClipToPadding(true);
      contacts_lv.setPadding(0,0,0,0);
   }
Gal Rom
źródło
2

Odpowiedź zegarmistrza jest najlepsza i całkiem sprytna. Możesz także utworzyć pusty widok stopki.

SIr Codealot
źródło
1
pierwsze rozwiązanie nie zadziałało, ale twoja sugestia zadziałała, naprawdę dobry pomysł, dziękuję
Badr
1

Dodaj te dwie linie do kodu XML listView:

android:transcriptMode="alwaysScroll"  
android:stackFromBottom="true"
Rohit Kumar
źródło
0

Innym rozwiązaniem może być wykonanie makiety widoku o określonej wysokości.

W twoim adapterze w getViewCount zwraca 2.

W getCount zwróć yourData.size + 1.

W getViewType sprawdź, czy element jest ostatnim elementem return 2;

Użyj tego typu w getView, aby zapełnić mockview.

minimalistyczny
źródło
-2

Chyba chcesz dodać margines tylko do ostatniej pozycji:

Możesz więc zrobić w ten sposób w swojej metodzie getview indeks elementu listy i sprawdzić, czy jest to ostatni element, a następnie dodać margines do widoku.

Głupkowaty
źródło
Opisałem ten sposób w sekcji „Dodaj dolny margines do ostatniej pozycji w implementacji adaptera”. Zastanawiam się, czy są bardziej eleganckie sposoby.
darja
Dlaczego nie chcesz tego robić w ten sposób?
Goofy
Zobacz wyjaśnienie, o którym mowa.
darja
Żadnych innych pomysłów - tak wydaje się być jedynym sposobem
darja
@Goofy Jak dodać margines do ostatniego wiersza widoku listy?
vrunoa