Search code examples
androidlistviewandroid-listviewmargins

How to tune width of listview, header and footer correctly?


I am using ListView and it has header and footer. The problem is that I need the list of items itself to be more narrow then a header. And I can't achieve that. The thing is that if I set paddings or margins to ListView, it will be set to list items, header and footer (the header and footer for some reason will be more narrow then list items). Settings margins just for item layout itself is no use. Here are the layouts:

main_layout.xml:

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

    <ListView
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

header_list_layout.xml:

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

    <EditText
        android:inputType="textPersonName" />

</RelativeLayout>

footer_list_layout.xml:

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

    <TextView
        android:layout_width ="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:textAppearance="?android:attr/textAppearanceLarge" />

</RelativeLayout>

list_item_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <TextView
        android:textStyle="bold"
        android:textColor="@android:color/black"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </TextView>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </TextView>

</LinearLayout>

So what can I do to make everything right?

The image how I want it to look: listview


Solution

  • You can set custom layout for the items in the ListView in the adapter. For example, if you use the ArrayAdapter, you can do something like this (Pay attention to the getView method):

    public class MySimpleArrayAdapter extends ArrayAdapter<String> {
      private final Context context;
      private final String[] values;
    
      public MySimpleArrayAdapter(Context context, String[] values) {
        super(context, R.layout.rowlayout, values);
        this.context = context;
        this.values = values;
      }
    
      @Override
      public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View rowView = inflater.inflate(R.layout.list_item, parent, false);
        TextView textView = (TextView) rowView.findViewById(R.id.label);
        ImageView imageView = (ImageView) rowView.findViewById(R.id.icon);
        textView.setText(values[position]);
        // change the icon for Windows and iPhone
        String s = values[position];
        if (s.startsWith("iPhone")) {
          imageView.setImageResource(R.drawable.no);
        } else {
          imageView.setImageResource(R.drawable.ok);
        }
    
        return rowView;
      }
    } 
    

    (Code copied from this tutorial)

    Then in your list_item.xml, add the padding to the LinearLayout, you will have a narrower view:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:orientation="vertical"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:background="#0000ff"
                  android:paddingLeft="10dp"
                  android:paddingRight="10dp"
        >
            <TextView
                android:id="@+id/tv1"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="#AAAA00"
                />
            <TextView
                android:id="@+id/tv2"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="#00aAAA"
                />
    </LinearLayout>
    

    You will get: layout1


    Or you can applying the margin to the individual TextView

    <?xml version="1.0" encoding="utf-8"?>
    
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:orientation="vertical"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:background="#0000ff"
        >
            <TextView
                android:id="@+id/tv1"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="#AAAA00"
                android:layout_marginLeft="10dp"
                android:layout_marginRight="10dp"
                />
            <TextView
                android:id="@+id/tv2"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="#00aAAA"
                android:layout_marginLeft="10dp"
                android:layout_marginRight="10dp"
                />
    </LinearLayout>
    

    you will get: layout2


    Or if you have many children views in the layout, you can wrap it with another LinearLayout (though it may impact performance) and apply margin on it

    <?xml version="1.0" encoding="utf-8"?>
    
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:orientation="vertical"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:background="#0000ff"
        >
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:background="#AAAAAA"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            >
    
            <TextView
                android:id="@+id/tv1"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="#AAAA00"
                />
            <TextView
                android:id="@+id/tv2"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="#00aAAA"
                />
            </LinearLayout>
    </LinearLayout>
    

    You will get: layout3