Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to round corners of list item at the top and bottom of the list view? (not only for top and bottom items)

I have a listview with rounded corner at the top and the bottom. Look like this image: enter image description here

But when I click on the top and the bottom of ListView, the List Item's background is rectangle not rounded as background of ListView at top and bottom. Like this image :

List item's corner not rounded

How to resolve this issue?

this is my code :

1/ list_activity.xml

<?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="#cacaca">

<ListView
    android:id="@+id/listView3"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="10dp"
    android:background="@drawable/list_border"
    android:listSelector="@drawable/list_selector"/>
</LinearLayout>

2/ list_border.xml

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#fff"/>
<corners android:bottomRightRadius="10dp"
    android:bottomLeftRadius="10dp"
    android:topLeftRadius="10dp"
    android:topRightRadius="10dp"/>
</shape>

3/ list_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true"
        android:drawable="@color/colorPrimary" />
</selector>

4/ ListActivity.java

ListView listView = (ListView)findViewById(R.id.listView3);

ArrayList<String> listItems = new ArrayList<>();

for(int i=0;i<20;i++){
    listItems.add(""+i);
}

ArrayAdapter<String> adapter = new ArrayAdapter<>(getApplicationContext(), android.R.layout.simple_selectable_list_item, listItems);
listView.setAdapter(adapter);
like image 252
Huo Chhunleng Avatar asked Feb 24 '16 02:02

Huo Chhunleng


2 Answers

This solution is not pretty but it does what you want. The idea is to invert the corner and draw them as foreground :

the ListView is wrapped in a FrameLayout :

<FrameLayout
      android:layout_width="match_parent"
      android:layout_height="0dp"
      android:layout_margin="10dp"
      android:foreground="@drawable/inverted_corners"
      android:layout_weight="1">
      <ListView
          android:id="@+id/listView3"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:background="#fff"
          android:listSelector="@drawable/list_selector" />
  </FrameLayout>

which foreground (drawable/inverted_corners.xml) is set to a rounded hole, drawn with the background color. The trick is to draw a line outside the shape, instead of a filled shape :

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:bottom="-11dp"
        android:left="-11dp"
        android:right="-11dp"
        android:top="-11dp">
        <shape android:shape="rectangle">
            <stroke
                android:width="10dp"
                android:color="#cacaca" />
            <corners android:radius="22dp" />
        </shape>
    </item>
</layer-list>

This garanties that the rounded corners are on top of the selector, and the overscroll effect.

like image 152
bwt Avatar answered Oct 31 '22 12:10

bwt


I suggest you should set the layout with corners to your ListView's first and last element, but not to the whole ListView.

You can create two extra .xml files in addition to your list_selector.xml: one for first element with the round corners at the top (lets call it list_selector_top.xml) and another one for the last element with the round corners at the bottom (list_selector_bottom.xml).

Then you can create your own MyAdapter extends ArrayAdapter and somewhere in getView() method set the appropriate background to your element's View (if position==0 set list_selector_top.xml, if position==getCount()-1 set list_selector_bottom.xml, by default set list_selector.xml).

It might be not the simpliest approach, but it works.

like image 1
Vasily Kabunov Avatar answered Oct 31 '22 13:10

Vasily Kabunov