How to combine the corners of a list item at the top and bottom of the list? (not only for upper and lower elements)

I have a list with a rounded corner at the top and bottom. Check out this image: enter image description here

But when I click at the top and bottom of the ListView, the List Element background is a rectangle not rounded as the ListView background above and below. Like this image:

List item corner not rounded

How to solve this problem?

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); 
+5
source share
6 answers

This solution is not very beautiful, but it does what you want. The idea is to invert the angle and draw them as the foreground:

ListView enclosed in 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> 

for which the foreground ( drawable/inverted_corners.xml ) has a rounded hole drawn in background color. The trick is to draw a line outside the form instead of the filled form:

 <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 ensures that rounded corners are on top of the selector, and the effect is overscroll.

+2
source

I suggest you set the layout with the corners on your ListView first and last element, but not on the entire ListView .

In addition to your list_selector.xml you can create two additional XML files: one for the first element with round corners at the top (lets call it list_selector_top.xml ), and the other for the last element with round corners at the bottom ( list_selector_bottom.xml ).

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

This may not be the easiest approach, but it works.

+1
source

Set the radius of the corner to the list view selector also with this:

 <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@android:id/list" android:state_pressed="true" > <shape> <solid android:color="@color/colorPrimary"/> <corners android:radius="10dp"/> </shape> </item> </selector> 

therefore your selection will not be the transverse border of the list view .

enter image description here

cons - you cannot determine which radius you should set both the top and bottom, so you need to set radius on all sides.

I hope that this helps, or at least give you some direction to solve your problem.

+1
source

If you can use FrameLayout as the parent for the ListView , then set the corner shape as foreground parent FrameLayout .

 <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:foreground="@drawable/list_border"> <ListView android:id="@+id/listView3" android:layout_width="match_parent" android:layout_height="wrap_content" android:listSelector="@drawable/list_selector"/> </FrameLayout> 

If you want to use LinearLayout as the parent of a ListView, then merge the ListView with ForegroundLinearLayout and set the corner shape as foreground to ForegroundLinearLayout .

What is ForegroundLinearLayout ? This is a LinearLayout with the LinearLayout property, like FrameLayout . Get the code from Chris Banes. https://gist.github.com/chrisbanes/9091754

Your code should be:

 <?xml version="1.0" encoding="utf-8"?> <ForegroundLinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:foreground="@drawable/list_border"> <ListView android:id="@+id/listView3" android:layout_width="match_parent" android:layout_height="wrap_content" android:listSelector="@drawable/list_selector"/> </ForegroundLinearLayout> 
+1
source

add an addition to your style. updated style here.
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"/> <padding android:left="10dp" android:right="10dp" android:top="10dp" android:bottom="10dp" /> </shape> 
+1
source

This can be done easily using the Android CardView support library. Just wrap the ListView in a CardView layout and set cardCornerRadius to a CardView , for example:

  <?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"> <android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto" android:layout_height="wrap_content" android:layout_width="match_parent" card_view:cardCornerRadius="10dp" > <ListView android:id="@+id/listView3" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:listSelector="@drawable/list_selector"/> </android.support.v7.widget.CardView> </LinearLayout> 

Remember to import the CardView support CardView :

 compile 'com.android.support:cardview-v7:23.1.1' 
+1
source

Source: https://habr.com/ru/post/1243723/


All Articles