ListView headers without list item separators
Asked Answered
W

4

7

I'm currently writing an Android app that uses ListView with headers. It works okay, but not really as I want. Every item in ListView has 1-2px separator at the top and bottom of it. So does the header - and that's the problem. It does not look very pretty...

Ugly separators between items and headers

The interesting part is that system apps (like Settings, for instance) does not have such problem.

Settings app

Here's my example adapter:

setListAdapter(new BaseAdapter() {
    @Override
    public int getCount() {
        return 10;
    }

    @Override
    public Object getItem(int i) {
        return i;
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        View v = ((LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE))
                .inflate(i % 3 == 0 ? R.layout.list_header : android.R.layout.simple_list_item_1, viewGroup, false);
        ((TextView)v.findViewById(android.R.id.text1)).setText("test");
        return v;
    }
});

And list header layout file:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Hello, World"
    style="?android:attr/listSeparatorTextViewStyle">

</TextView>

So the question is: how to get rid of the item separators between headers and regular items, just like, for example, Settings app does?

EDIT: After reading the answers, I want to clear one thing up. I do not want to remove separators completely. I want to remove them only between the header items and regular items. Also, half-measures like "removing separators completely and adding them on some items" do not satisfy me, too.

Walczak answered 1/5, 2014 at 11:3 Comment(3)
You can definitely get that appearance by using the Preference APIs and creating a PreferenceCategory for each header - I'm assuming this is what the Settings app does.Delainedelainey
@Delainedelainey yes, you're right - although, there are other system apps that behave like that. For example, People app - I don't think it's using Preference API to achieve such appearance. :)Walczak
Good point, and I don't know how they might do it. Maybe they pulled some of the code out of the Preference APIs.Delainedelainey
V
0

It seems that you have to use a custom item view for dividers and a little workaround. Let me explain how to manage this:

  • Do not use the default dividers, remove it.
  • Create a custom layout with a View at bottom to be the subline for headers.
  • Create a custom layout with a View at top to have the divider for items.

Then, the two types of dividers will be glue to make only one subline for header part, so dividers should have the same height in order to make a good subline. This will avoid to have a divider above the header sections but keeping the dividers for items list.

Therefore, let me show some code to achieve it. First, don't forget to avoid default divider on the ListView:

<ListView
    android:id="@+id/listview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:divider="@null"
    android:dividerHeight="0dp"/>

Create an item layout with a divider at top set to 1dp (or whatever):

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <!-- this is the divider for items -->
    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="@android:color/darker_gray"/>

    <!-- and the rest of item's content in another ViewGroup -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="10dp"
        android:orientation="horizontal">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_launcher"/>

        <TextView
            android:id="@+id/item_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingLeft="15dp"
            android:textColor="@android:color/white"/>
    </LinearLayout>
</LinearLayout>

Finally, the header layout with a divider at bottom (with the same height as item's divider):

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/item_header"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        style="?android:attr/listSeparatorTextViewStyle"/>

    <!-- this is the ("half-")divider for header section -->
    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="@android:color/darker_gray"/>
    <!-- this view above will be merged with item's dividers -->
</LinearLayout>

And it gives this result:

Volk answered 24/12, 2015 at 15:37 Comment(0)
C
-1

Remove the style you have set for the header TextView

Create your own custom style with required divider and set it to TextView

  <style name="CustomListSeperatorTextViewStyle" parent="Widget.TextView.ListSeparator">
<item name="android:background">@drawable/your_own_here</item>

Cai answered 1/5, 2014 at 11:15 Comment(1)
It does not work for me. It only changes appearance of list item, but it does not remove the separators.Walczak
L
-1

Seperator is due to the style you have set with the textview, just remove the style hope this will work.

Loch answered 1/5, 2014 at 11:30 Comment(2)
Do you mean removing the 'style="?android:attr/listSeparatorTextViewStyle"' part? It does not work (and I don't see reason why it should since the separators are added by ListView itself, not by the items).Walczak
Try one more thing. Check did you have some thing like this in your xml where you have specified listView android:dividerHeight="2.0dp" try to remove it.Loch
F
-1

I just found these parameters that seem to be what you need, you can try adding them in your ListView:

android:headerDividersEnabled="false"
android:footerDividersEnabled="false"

The documentation is available here and indicates:

When set to false, the ListView will not draw the divider after each header view. The default value is true.

Feliciafeliciano answered 1/5, 2014 at 11:58 Comment(2)
That does not really answer my question. I've updated it now.Walczak
It still does not answer my question anyway. These parameters are used with header and footer views, which are just views that are either placed on top or the bottom of the ListView - but what I really need is to place my section headers actually in the middle of the ListView.Walczak

© 2022 - 2024 — McMap. All rights reserved.