4

Is it possible to have a margin/padding for the ListView without having the margin applied to the header? I want my ListView to be like the Google Now layout. I've got everything working except for this little problem.

Question: Is it possible to not have layout parameters of the ListView apply to its header?

EDIT1:More info

The purple view is the header to the listView. I have tried adding margin to the list item layout.This doesnt work either. All i need is a way to apply margin to the listview so that it doesnt apply the margin to the header in the listView.

EDIT2: My layouts header.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:orientation="vertical" >

    <View
        android:layout_width="match_parent"
        android:layout_height="@dimen/top_height"
        android:background="@color/top_item" />

    <View
        android:id="@+id/placeholder"
        android:layout_width="match_parent"
        android:layout_height="@dimen/sticky_height"
        android:layout_gravity="bottom" />

</FrameLayout>

root_list.xml

<LinearLayout>
<com.test.CustomListView
    android:id="@android:id/list"
    android:layout_marginLeft="16dp"
    android:layout_marginRight="16dp"
    android:layout_height="wrap_content" /></LinearLayout>

list_item.xml

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

<TextView
    android:id="@+id/textview_note"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

<TextView
    android:id="@+id/textview_note_date"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/></LinearLayout>

I've removed uselsess layout properties here due to length of this post. This is how it looks

avatsav
  • 1,208
  • 1
  • 8
  • 16
  • 1
    Apply padding equally for all items and don't apply padding to Header View. – TNR Dec 27 '12 at 07:37
  • I think you mean adding margin to the listItem layout.It didnt work. – avatsav Dec 27 '12 at 07:50
  • I mean adding padding to every list item layout item. and don't add the same to Header. – TNR Dec 27 '12 at 07:51
  • you mean adding padding programatically to each and every item in the listview in the adapter? – avatsav Dec 27 '12 at 07:56
  • if you add item layout code then I can suggest. I am suggesting you to change the item layout not programmatically – TNR Dec 27 '12 at 08:03
  • Adding paddig/margin to the list item didnt work I tried that already. I can nest the whole thing in a linear layout and get the effect i need but the whole listItem is selectable rather than the desired part – avatsav Dec 27 '12 at 08:09
  • came across this in 2014 (after Android's Material Design was introduced), and looks like Google is just following in your footsteps – woojoo666 Aug 21 '14 at 19:00

4 Answers4

7

After much digging around i found that its is not posssible to decouple the listView layout params from its headers and the header is part of listView. So in order to get the desirred margin effect, After much looking around I found out that adding margin to your root of the layout in the list view item didnt work. So I added another dummy LinearLayout inside the existing root LinearLayout(a nested LinearLayout) and added the children inside the nested layout.Now setting margin to the inner layout gives the desired effect.

Code:

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginRight="16dp"
        android:layout_marginLeft="16dp"
        android:background="@drawable/list_selector"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/textview_note"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <TextView
            android:id="@+id/textview_note_date"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>

</LinearLayout>
avatsav
  • 1,208
  • 1
  • 8
  • 16
  • 3
    You can remove the outer LinearLayout and instead of `android:layout_marginRight="16dp" android:layout_marginLeft="16dp"` put `android:paddingLeft="16dp" android:android:paddingRight="16dp"` or at least use an outer FrameLayout instead of LinearLayout – vovahost Jul 31 '13 at 08:14
0

In your header part, add the following tag:

android:layout_alignParentLeft="true"

this will solve your problem.

Rohit
  • 490
  • 3
  • 15
  • my header is an xml that I inflate programatically and add the the list by listView.addHeaderView(headerView). The header is bound to the listView. So chaning margins of the listview will obviously change the header. I tried your suggestion on the header.xml but it doesnt work. – avatsav Dec 27 '12 at 08:02
  • what layout are you using on your root? – Rohit Dec 27 '12 at 08:05
  • it will work only when you are using Relative layout outside the listview. – Rohit Dec 27 '12 at 08:19
  • This isnt the solution sorry.The question is to not have layout parameters of the listview apply to its header. Edited the question with more information – avatsav Dec 27 '12 at 08:25
  • Apply margin in your list_item.xml rather than root_list.xml. It will work for sure. – Rohit Dec 27 '12 at 09:24
  • I got it working. The listView doesnt take layout margin for the lsitItem's root view. So I had to find another way.Check my answer. – avatsav Dec 27 '12 at 12:34
  • It's good. But i don't think you need 2 linear layout it can be done with 1 layout also. I posted the same solution, then you just said you have applied but i did not help you. Otherwise declaring useless layout may lead you to the runtime exception on some devices. – Rohit Dec 28 '12 at 04:56
  • adding layout_margin for the root linear layout will not apply the margin.I tested and posted the solution. – avatsav Dec 31 '12 at 10:58
0
// Temp is the root view that was found in the xml
final View temp = createViewFromTag(root, name, attrs, false);

ViewGroup.LayoutParams params = null;

if (root != null) {
    if (DEBUG) {
        System.out.println("Creating params from root: " +
                root);
    }
    // Create layout params that match root, if supplied
    params = root.generateLayoutParams(attrs);
    if (!attachToRoot) {
        // Set the layout params for temp if we are not
        // attaching. (If we are, we use addView, below)
        temp.setLayoutParams(params);
    }

// We are supposed to attach all the views we found (int temp)
// to root. Do that now.
if (root != null && attachToRoot) {
    root.addView(temp, params);
}

// Decide whether to return the root that was passed in or the
// top view found in xml.
if (root == null || !attachToRoot) {
    result = temp;
}

...
return result;

this is the code of LayoutInflater,as you can see ,if you add a root,it's not null,generated the layoutParams from root.

and then if the thrid param is false,there is only make temp.setLayoutParams(params) which params is generated by root!! and the temp is as return....

if attachToRoot is true,root will execute root.addView(temp, params),and then the root is as return..

if you just do LayoutInflater.from(this).inflate(R.layout.popup_choose_type, null);,and if you had set some attribute as paddingBottom,it will surprised you that is will not work!!because of loss LayoutParams!

As for how to solve it,you can see here

Community
  • 1
  • 1
joe
  • 619
  • 6
  • 10
-1

you can do it by give margin in listview's layout file then you will get it the output.

Vatsal Shah
  • 42
  • 1
  • 6