Android: ListView with rounded corners
In my last project I needed to implement a ListView with rounded corners, because the app had to be supplied for Android and iPhone and they needed to look somewhat alike.
In this blogpost, I want to show you how I’ve implemented it and hopefully help some people who also want to use ListViews with rounded corners:
First off, we need the drawables for the backgrounds of the Lists entries:
For the entries in the middle of the list, we don’t need rounded corners, so create a xml in your drawable folder “list_entry_middle.xml” with following content:
<?xml version="1.0" encoding="UTF-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item> <shape> <stroke android:width="1px" android:color="#ffbbbbbb" /> </shape> </item> <item android:bottom="1dp" android:left="1dp" android:right="1dp"> <shape > <solid android:color="#ffffffff" /> </shape> </item> </layer-list>
For the rounded corners, create another xml, “rounded_corner_top.xml”:
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item> <shape> <stroke android:width="1dp" android:color="#ffbbbbbb" /> <corners android:topLeftRadius="20dp" android:topRightRadius="20dp" /> </shape> </item> <item android:top="1dp" android:left="1dp" android:right="1dp" android:bottom="1dp"> <shape > <solid android:color="#ffffffff" /> <corners android:topLeftRadius="20dp" android:topRightRadius="20dp" /> </shape> </item> </layer-list>
Implementing the bottom part is quite the same, just with bottomLeftRadius and bottomRightRadius. (maybe also create one with all corners rounded, if the list only has one entry)
For better usability, also provide drawables with other colors for the different states, that the list item can have and reference them in another xml in the drawable folder (“selector_rounded_corner_top.xml”) as followed:
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/rounded_corner_top_click" android:state_pressed="true" /> <item android:drawable="@drawable/rounded_corner_top_click" android:state_focused="true" /> <item android:drawable="@drawable/rounded_corner_top" /> </selector>
Now do the same for the other backgrounds of the list.
All that is left now, is to assign the right backgrounds in our ListAdapter like following:
@Override public View getView(int position, View convertView, ViewGroup parent) { //... //skipping the view reuse stuff if (position == 0 && entry_list.size() == 1) { view.setBackgroundResource(R.drawable.selector_rounded_corner); } else if (position == 0) { view.setBackgroundResource(R.drawable.selector_rounded_corner_top); } else if (position == entry_list.size() - 1) { view.setBackgroundResource(R.drawable.selector_rounded_corner_bottom); } else { view.setBackgroundResource(R.drawable.selector_middle); } //... //skipping the filling of the view }
Aaaand we’re done.
mahdi
Thanks. can you put an ScreenShot?
Tobias Knell
Sorry, I don't have the example project for this anymore, so I can't make a screenshot of it.
mahdi
please insert your project screen shot
Tobias Knell
Hi Bojan,
for me, it sounds like there should be something wrong in your view reusage. If you provide your getView() code, I could check it.
Bojan
Dear Tobaias,
your work help me a lot, but I still have little problem. I manage to make rounded listview and selection(highlighted) items are in bounders but my problem is- when I for example, scroll list down my rounded part is lost- it became straight, I lose rounded shape. Any help?
Say
Hello dude, may I ask what is the variable entry_list?
Tobias Knell
Just the list of entries for the ListView.
Jaume
Thanks! This post helped me a lot! :)
MIchal
Hey, good article, i am creating similar ListView.
Just one note, dont forget set android:listSelector="@android:color/transparent" in your listView to eliminate standard selected row background color which is visible around selected rounded top/ bottom corners.
Surya
Hi... Nice work..
I have a question here... I could implement the same but when I click on the top item in the LIST VIEW it doesn't give me round corners in ITEM PRESSED STATE..
Please help
Thanks,
Surya
Tobias Knell
Are you sure you are using the selector as the drawable for the item? Make sure that it has "state_pressed" declared like the following:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/rounded_corner_top_click"
android:state_pressed="true" />
<item android:drawable="@drawable/rounded_corner_top_click"
android:state_focused="true" />
<item android:drawable="@drawable/rounded_corner_top" />
</selector>
Tobias Knell
I don't want to explain the basics of the basics in every post. In this post, there is everything you need to achieve the rounded corners for a ListView, just read the text and think a bit for yourself. I don't want to provide a working example just for copy&paste.
Andrey
This article useful just for 25% as explains how to make it just for 1/4 of task. (:
This post useful just as idea or concept.
ed
Hi Tobias. Great post. But I don't understand how to implement all together.
I'm learning android and I would like to have an example to view all in action.
Is it possible? Thanks in advance
Tobias Knell
If you're new to Android, you can try to learn the basics here: http://developer.android.com/guide/components/index.html
For this example, try searching for Android ListView, Android ListAdapter, Android Drawable with XML... There are many guides out there that state the things that I use in this blog in detail. So try to read a few of them first to understand all the different components better. After that it will be no problem for you to follow this blog :)
Oscar de la Pena
Great post. This is really helpful
Tobias Knell
Stimmt, das hatte ich wohl übersehen. Damit muss man auch der convertView keinen Background mehr zuweisen, da dieser sich für die verschiedenen item types nicht mehr ändert.
Danke für den Tipp!
Marcus
Alternativ dazu gibt es bei der ListView auch addFooterVIew und addHeaderView (die vor respektive nach den eigentlichen listitems mit im scrollbereich hängen).
ListView hat ebenfalls sowas wie item types, wenn da für das erste und das letzte entsprechende Types zurückbekommen, bekommt man eine andere convertView hereingereicht, und kann davon ausgehen, dass diese nach dem ertsmaligen erzeugen auch vom framework wieder reingereicht wird :)