Add margin above top ListView item (and below last) in Android

AndroidAndroid LayoutAndroid Listview

Android Problem Overview


This is a pretty fine question about the layout of items in a ListView in Android.

I have an activity with a title bar at the top and a ListView taking up the rest of the screen. I want my ListView to appear with 10dp padding on the left, right and top, but when you scroll the ListView up, I want it to cover the top 10dp padding before disappearing under the faded edge. Similarly, when you scroll to the bottom, the last list item should appear with 10dp between the bottom of the last list item and the actual bottom of the screen (if you're wondering why, it's because there's a pretty background image that I want poking out around the ListView).

I've tried adding padding to the ListView itself, but then when you scroll the list it disappears under the edge of the padding.

I'm from a web dev background, and the analogy would be to add margin above the first list item (and below the last list item).

Android Solutions


Solution 1 - Android

You wrote:

> I've tried adding padding to the ListView itself, but then when you scroll the list it disappears under the edge of the padding.

Set ListView's clipToPadding attribute to false. This will enable padding around the ListView and scrolling to the end of the layout (and not only to the edge of the padding).

An example:

<ListView
    android:id="@+id/list_view"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:divider="@android:color/transparent"
    android:dividerHeight="10.0sp"
    android:padding="16dip"
    android:clipToPadding="false"/>

android:clipToPadding is an XML attribute of ViewGroup, the base class for layouts and views containers.

The related method call is:

public void setClipToPadding (boolean clipToPadding)

Solution 2 - Android

Space padding = new Space(this);
padding.setHeight(20); // Can only specify in pixels unfortunately. No DIP :-(

ListView myListView = (ListView) findViewById(R.id.my_list_view);

myListView.addHeaderView(padding);
myListView.addFooterView(padding);

myListView.setAdapter(myAdapter);

The above ListView will have a header and footer padding of 20 pixels.

Solution 3 - Android

Appendage to @Jakobud's answer...

My listView was already making use of the android:divider/android:dividerHeight properties to create transparent gaps between listView items. This allowed me to simply add the android:headerDividersEnabled and android:footerDividersEnabled properties and set the Header and Footer views to new View(Activity.this).

Slight simplification for cases where you already have dividers setup in the listView.

Solution 4 - Android

My solution using a ListFragment, based on the solutions by @Jakobud and @greg7gkb.

ListView listView = getListView();
listView.setDivider(null);
listView.setDividerHeight(getResources().getDimensionPixelSize(R.dimen.divider_height));
listView.setHeaderDividersEnabled(true);
listView.setFooterDividersEnabled(true);
View padding = new View(getActivity());
listView.addHeaderView(padding);
listView.addFooterView(padding);

Solution 5 - Android

@Gunnar Karlsson's answer is good, but has an issue of cell views being recycled prematurely when completely behind the padding, but not yet fully off the screen. Setting clipToPadding=false is responsible for this and may or may not be fixed in a future version of android.(https://stackoverflow.com/questions/15915226/when-using-cliptopadding-in-listviews-the-items-get-recycled-prematurely)

I have a nice simple solution with no side effects:

  1. Add an outer (Linear or Relative) Layout to your cell_design.xml
  2. On this outer Layout add padding (i.e. 10dip) to create a "margin" around the whole cell. (N.B. only padding will work, not margin on the outer layout)
  3. On the ListView set android:dividerHeight="-10dip", the opposite of what is around the cell

Compared to the other answer, there is no need to set the divider colour. The padding at the topmost and bottommost cells will be present, and the negative divider will prevent double height dividers in between.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMick ByrneView Question on Stackoverflow
Solution 1 - AndroidonosendaiView Answer on Stackoverflow
Solution 2 - AndroidJake WilsonView Answer on Stackoverflow
Solution 3 - Androidgreg7gkbView Answer on Stackoverflow
Solution 4 - AndroidhleinoneView Answer on Stackoverflow
Solution 5 - AndroidJamesView Answer on Stackoverflow