Separator (divider) after last item of ListView
Asked Answered
A

6

55

When I create a simple layout with only a ListView in it, there is no separator displayed after the last item, which looks a bit ugly.

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

    <ListView
        android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true" />
</RelativeLayout>

enter image description here

However, I found out that a separator is displayed after the last item if I add another view bellow the listview and set the android:layout_above attribute for the listview.

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

    <ListView
        android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/bottom"
        android:layout_alignParentTop="true" />

    <TextView
        android:id="@+id/bottom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:background="@android:color/holo_blue_dark"
        android:text="Bottom" />
</RelativeLayout>

enter image description here

Why does the listview behave like this? How can I get a separator after the last item in a layout that contains only a listview?

Accept answered 7/1, 2013 at 15:48 Comment(6)
How can I get a separator after the last item in a layout that contains only a listview? - If you have only a ListView in the layout I think you could always(and pretty easy) implement an adapter that adds an extra empty row to force showing the target divider.Kinder
That's interesting, but won't that last item be clickable?Accept
Not if you override the isEnabled(position) method of the adapter to return false for that empty last position.Kinder
Change ListView height 'from wrap_content' to 'fill_parent'......it might work as it worked for me.Civilize
@Civilize provided the correct answer nearly a month before Kzinch!Davao
Yay @ASP! Too bad someone else took credit for your answer.Bryozoan
I
103

The answer is very simple: you should change android:layout_height="wrap_content" to android:layout_height="match_parent" in your ListView.

You can probably guess why this happens.

Inexpressible answered 8/1, 2014 at 17:13 Comment(7)
What if you have content under the ListView though? In my case I am making a nav drawer with several sections.Crazyweed
You saved me. I never knew about this. Thanks @KzinchPimp
@Vitali Olshevski: can you explain why this happens?? Thank you for your answer...Cenacle
@Cenacle You see, the separation line is not drawn when the lower bound of the last item in ListView matches the lower bound of ListView itself. This exact case happens when you use wrap_content. But when you use match_parent the lower bound of ListView is different from the lower bound of the last item in the list. There is some extra empty space between them that is visually separated by the additional separation line after the last item. It is the simplest explanation of the behaviour. I hope this helps.Inexpressible
It also works with wrap_content using empty custom footer myList.addFooterView(new View(context)) as mentioned belowSamuella
@konopko adding an empty view looks like a smelly hack. but it may help someone, so good to know.Inexpressible
Thanks, this answer saved my time. Also in my case, ve sure listview's parent view height also match_parent.Josphinejoss
C
15

Have you tried this one ?

android:footerDividersEnabled="true"

if not try this out

<View
android:background="#00ff00"
android:layout_width="fill_parent"
android:layout_height="3dp"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="@+id/YOUR_LIST_ID" />
Critter answered 7/1, 2013 at 16:6 Comment(6)
This doesn't really help. According to developer.android.com/reference/android/widget/… the default value is true.Accept
Well, this might work, but as I already commented on Appu's answer, this kind of colour and dimension guessing is just a hack that simply won't look consistent with the other separators. If I just compare your and Appu's values, the colour and height of the line are very different (and possibly none of them is the same as the actual colour and height of the default separators).Accept
Try to match with a colour and height that would nearly match with the requirements then as a work around!Critter
But what if the values are dependent on the theme of the given device? There are the Holo theme, the Android 2.x themes and various vendor-specific GUIs. I don't really like hardcoding some randomly guessed values, sorry.Accept
Thanks for bringing this out: android:footerDividersEnabledHenderson
Um, hello! You are all 99% there , thanks for pointing me in the right direction :) myList.addHeaderView(new View(context)); myList.addFooterView(new View(context));Duodecimal
D
9

Add an empty view to top (and/or bottom) to create a divider on top (or bottom)

myList.addHeaderView(new View(context));
myList.addFooterView(new View(context));
Duodecimal answered 14/5, 2015 at 1:1 Comment(1)
This works best for me since I have stylistic options applied to the listview that I don't have to worry about matchingLanai
A
1

I've come with a hack that works around this problem. Since the last separator is displayed only if another view follows the list view, it is possible to make that second view invisible by setting its layout_height to 0dp.

It's still a hack, but it makes to last divider look consistent with the other, so it's better that trying to manually create a horizontal line with trying to guess the right colour and dimensions.

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

    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/invisible"
        android:layout_alignParentTop="true" />

    <View
        android:id="@+id/invisible"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_alignParentBottom="true" />    
</RelativeLayout>
Accept answered 7/1, 2013 at 17:59 Comment(1)
If you add padding to the bottom of your listview, that will also work. I used: android:paddingBottom="10dp"Sacrament
H
1

I do something similar to what @Natix describes, but instead of messing with the containing layout of the list I simply add the empty view as a footer on the list via ListView.addFooterView()

Harwin answered 30/4, 2013 at 18:44 Comment(0)
O
0

It seems somewhat different when your listview is displayed if you code it like that. But even you can follow this too.

First define a style named Line

<style name="Line">
    <item name="android:layout_width">fill_parent</item>
    <item name="android:layout_height">2px</item>
    <item name="android:background">@color/white</item>
</style>

// In the above style you can change the height of the line as per your requirement.

Wherever you want to use the above line, you can declare it like this in your xml file.

<LinearLayout
android:orientation = "vertical"
.......................
............................>
 <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
         />


<View
        style="@style/Line"/>

</LinearLayout>

The above code creates a line under your listview. The above code is most useful when you wanna use it in various places in your project. Or if want at only one place, you can do it like this.

 <LinearLayout
    android:orientation = "vertical"
    .......................
    ............................>
     <ListView
            android:id="@android:id/list"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
             />
<View
    android:layout_width="fill_parent"
        android:layout_height="1px"
        android:background="#20b2aa" />

</LinearLayout>

Hope this helps. BTW The reason is vague and even once I did search for this and I followed this way which I explained above.

Olshausen answered 7/1, 2013 at 16:7 Comment(2)
I appreciate your effort, but this is really just a hack. I don't want to be guessing colours, widths etc. They need to be the same as the other separators in the list view - their appearance can depend on the theme of the app or the whole device. Hardcoding some randomly guessed values is a way to hell. There has to be some more idiomatic solution, because the last separator did automatically appear in the second case.Accept
As I already mentioned in my answer that the reason is unknown and I did search a lot once. Let's hope someone will clarify this and give a clear solution.Olshausen

© 2022 - 2024 — McMap. All rights reserved.