如何在 Android 中创建带圆角的 ListView?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1683185/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I create a ListView with rounded corners in Android?
提问by Legend
How do I create a ListView with rounded corners in Android?
如何在 Android 中创建带圆角的 ListView?
回答by Legend
Here is one way of doing it (Thanks to Android Documentation though!):
这是一种方法(尽管感谢 Android 文档!):
Add the following into a file (say customshape.xml) and then place it in (res/drawable/customshape.xml)
将以下内容添加到文件中(比如 customshape.xml),然后将其放入(res/drawable/customshape.xml)
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="#SomeGradientBeginColor"
android:endColor="#SomeGradientEndColor"
android:angle="270"/>
<corners
android:bottomRightRadius="7dp"
android:bottomLeftRadius="7dp"
android:topLeftRadius="7dp"
android:topRightRadius="7dp"/>
</shape>
Once you are done with creating this file, just set the background in one of the following ways:
完成创建此文件后,只需通过以下方式之一设置背景:
Through Code:listView.setBackgroundResource(R.drawable.customshape);
通过代码:listView.setBackgroundResource(R.drawable.customshape);
Through XML, just add the following attribute to the container (ex: LinearLayout or to any fields):
通过 XML,只需将以下属性添加到容器(例如:LinearLayout 或任何字段):
android:background="@drawable/customshape"
Hope someone finds it useful...
希望有人觉得它有用...
回答by Kevin Parker
Although that did work, it took out the entire background colour as well. I was looking for a way to do just the border and just replace that XML layout code with this one and I was good to go!
虽然这确实有效,但它也去掉了整个背景颜色。我正在寻找一种方法来做边框,然后用这个替换那个 XML 布局代码,我很高兴去!
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke android:width="4dp" android:color="#FF00FF00" />
<padding android:left="7dp" android:top="7dp"
android:right="7dp" android:bottom="7dp" />
<corners android:radius="4dp" />
</shape>
回答by alvins
@kris-van-bael
@kris-van-bael
For those having issues with selection highlight for the top and bottom row where the background rectangle shows up on selection you need to set the selector for your listview to transparent color.
对于那些在选择高亮显示背景矩形的顶部和底部行有问题的人,您需要将列表视图的选择器设置为透明颜色。
listView.setSelector(R.color.transparent);
In color.xml just add the following -
在 color.xml 中添加以下内容 -
<color name="transparent">#00000000</color>
回答by Richard Le Mesurier
Update
更新
The solution these days is to use a CardView
with support for rounded corners built in.
这些天的解决方案是使用CardView
内置圆角支持。
Original answer*
原答案*
Another way I found was to mask out your layout by drawing an image over the top of the layout. It might help you. Check out Android XML rounded clipped corners
我发现的另一种方法是通过在布局顶部绘制图像来掩盖您的布局。它可能会帮助你。查看Android XML 圆角剪裁
回答by dr_g
The other answers are very useful, thanks to the authors!
其他答案非常有用,感谢作者!
But I could not see how to customise the rectangle when highlighting an item upon selection rather than disabling the highlighting @alvins @bharat dojeha.
但是在选择时突出显示项目而不是禁用突出显示@alvins @bharat dojeha 时,我看不到如何自定义矩形。
The following works for me to create a rounded list view item container with no outline and a lighter grey when selected of the same shape:
The following works for me to create a rounded list view item container with no outline and a lighter grey when selected of the same shape:
Your xml needs to contain a selector such as e.g. ( in res/drawable/customshape.xml):
您的 xml 需要包含一个选择器,例如(在 res/drawable/customshape.xml 中):
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" >
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<stroke android:width="8dp" android:color="@android:color/transparent" />
<padding android:left="14dp" android:top="14dp"
android:right="14dp" android:bottom="14dp" />
<corners android:radius="10dp" />
<gradient
android:startColor="@android:color/background_light"
android:endColor="@android:color/transparent"
android:angle="225"/>
</shape>
</item>
<item android:state_pressed="false">
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<stroke android:width="8dp" android:color="@android:color/transparent" />
<padding android:left="14dp" android:top="14dp"
android:right="14dp" android:bottom="14dp" />
<corners android:radius="10dp" />
<gradient
android:startColor="@android:color/darker_gray"
android:endColor="@android:color/transparent"
android:angle="225"/>
</shape>
</item>
Then you need to implement a list adapter and override the getView method to set the custom selector as background
然后你需要实现一个列表适配器并覆盖getView方法将自定义选择器设置为背景
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//snip
convertView.setBackgroundResource(R.drawable.customshape);
//snip
}
and need to also 'hide' the default selector rectangle e.g in onCreate (I also hide my thin grey divider line between the items):
并且还需要“隐藏”默认选择器矩形,例如在 onCreate 中(我还隐藏了项目之间的细灰色分隔线):
listView.setSelector(android.R.color.transparent);
listview.setDivider(null);
This approach solves a general solution for drawables, not just ListViewItem with various selection states.
这种方法解决了可绘制对象的通用解决方案,而不仅仅是具有各种选择状态的 ListViewItem。
回答by William Morrison
Yet another solution to selection highlight problems with first, and last items in the list:
选择突出显示列表中第一个和最后一个项目的问题的另一种解决方案:
Add padding to the top and bottom of your list background equal to or greater than the radius. This ensures the selection highlighting doesn't overlap with your corner curves.
在列表背景的顶部和底部添加等于或大于半径的填充。这可确保选择突出显示不会与您的角曲线重叠。
This is the easiest solution when you need non-transparent selection highlighting.
当您需要非透明选择突出显示时,这是最简单的解决方案。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<solid android:color="@color/listbg" />
<stroke
android:width="2dip"
android:color="#D5D5D5" />
<corners android:radius="10dip" />
<!-- Make sure bottom and top padding match corner radius -->
<padding
android:bottom="10dip"
android:left="2dip"
android:right="2dip"
android:top="10dip" />
</shape>
回答by Machado
This was incredibly handy to me. I would like to suggest another workaround to perfectly highlight the rounded corners if you are using your own CustomAdapter
.
这对我来说非常方便。如果您使用自己的CustomAdapter
.
Defining XML Files
定义 XML 文件
First of all, go inside your drawable folder and create 4 different shapes:
首先,进入 drawable 文件夹并创建 4 个不同的形状:
shape_top
<gradient android:startColor="#ffffff" android:endColor="#ffffff" android:angle="270"/> <corners android:topLeftRadius="10dp" android:topRightRadius="10dp"/>
shape_normal
<gradient android:startColor="#ffffff" android:endColor="#ffffff" android:angle="270"/> <corners android:topLeftRadius="10dp" android:topRightRadius="10dp"/>
shape_bottom
<gradient android:startColor="#ffffff" android:endColor="#ffffff" android:angle="270"/> <corners android:bottomRightRadius="10dp" android:bottomRightRadius="10dp"/>
shape_rounded
<gradient android:startColor="#ffffff" android:endColor="#ffffff" android:angle="270"/> <corners android:topLeftRadius="10dp" android:topRightRadius="10dp" android:bottomRightRadius="10dp" android:bottomRightRadius="10dp"/>
shape_top
<gradient android:startColor="#ffffff" android:endColor="#ffffff" android:angle="270"/> <corners android:topLeftRadius="10dp" android:topRightRadius="10dp"/>
shape_normal
<gradient android:startColor="#ffffff" android:endColor="#ffffff" android:angle="270"/> <corners android:topLeftRadius="10dp" android:topRightRadius="10dp"/>
shape_bottom
<gradient android:startColor="#ffffff" android:endColor="#ffffff" android:angle="270"/> <corners android:bottomRightRadius="10dp" android:bottomRightRadius="10dp"/>
shape_rounded
<gradient android:startColor="#ffffff" android:endColor="#ffffff" android:angle="270"/> <corners android:topLeftRadius="10dp" android:topRightRadius="10dp" android:bottomRightRadius="10dp" android:bottomRightRadius="10dp"/>
Now, create a different row layout for each shape, i.e. for shape_top
:
现在,为每个形状创建不同的行布局,即shape_top
:
You can also do this programatically changing the background.
<TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginLeft="20dp" android:layout_marginRight="10dp" android:fontFamily="sans-serif-light" android:text="TextView" android:textSize="22dp" /> <TextView android:id="@+id/txtValue1" android:layout_width="match_parent" android:layout_height="48dp" android:textSize="22dp" android:layout_gravity="right|center" android:gravity="center|right" android:layout_marginLeft="20dp" android:layout_marginRight="35dp" android:text="Fix" android:scaleType="fitEnd" />
您也可以以编程方式更改背景。
<TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginLeft="20dp" android:layout_marginRight="10dp" android:fontFamily="sans-serif-light" android:text="TextView" android:textSize="22dp" /> <TextView android:id="@+id/txtValue1" android:layout_width="match_parent" android:layout_height="48dp" android:textSize="22dp" android:layout_gravity="right|center" android:gravity="center|right" android:layout_marginLeft="20dp" android:layout_marginRight="35dp" android:text="Fix" android:scaleType="fitEnd" />
And define a selector for each shaped-list, i.e. for shape_top
:
并为每个形状列表定义一个选择器,即shape_top
:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Selected Item -->
<item android:state_selected="true"
android:drawable="@drawable/shape_top" />
<item android:state_activated="true"
android:drawable="@drawable/shape_top" />
<!-- Default Item -->
<item android:state_selected="false"
android:drawable="@android:color/transparent" />
</selector>
Change your CustomAdapter
更改您的自定义适配器
Finally, define the layout options inside your CustomAdapter
:
最后,在你的里面定义布局选项CustomAdapter
:
if(position==0)
{
convertView = mInflater.inflate(R.layout.list_layout_top, null);
}
else
{
convertView = mInflater.inflate(R.layout.list_layout_normal, null);
}
if(position==getCount()-1)
{
convertView = mInflater.inflate(R.layout.list_layout_bottom, null);
}
if(getCount()==1)
{
convertView = mInflater.inflate(R.layout.list_layout_unique, null);
}
And that's done!
大功告成!
回答by pawan kumar
to make border u have to make another xml file with property of solid and corners in the drawable folder and calls it in background
要制作边框,您必须在可绘制文件夹中制作另一个具有实体和角属性的 xml 文件,并在后台调用它
回答by android developer
actually, i think the best solution is described on this link:
实际上,我认为此链接中描述了最佳解决方案:
http://blog.synyx.de/2011/11/android-listview-with-rounded-corners/
http://blog.synyx.de/2011/11/android-listview-with-rounded-corners/
in short, it uses a different background for the top, middle and bottom items, so that the top and bottom ones would be rounded.
简而言之,它对顶部、中间和底部项目使用不同的背景,因此顶部和底部项目将被圆角化。
回答by mbonnin
I'm using a custom view that I layout on top of the other ones and that just draws the 4 small corners in the same color as the background. This works whatever the view contents are and does not allocate much memory.
我正在使用一个自定义视图,我将其布局在其他视图之上,并且只绘制与背景颜色相同的 4 个小角。无论视图内容是什么,这都有效,并且不会分配太多内存。
public class RoundedCornersView extends View {
private float mRadius;
private int mColor = Color.WHITE;
private Paint mPaint;
private Path mPath;
public RoundedCornersView(Context context) {
super(context);
init();
}
public RoundedCornersView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.RoundedCornersView,
0, 0);
try {
setRadius(a.getDimension(R.styleable.RoundedCornersView_radius, 0));
setColor(a.getColor(R.styleable.RoundedCornersView_cornersColor, Color.WHITE));
} finally {
a.recycle();
}
}
private void init() {
setColor(mColor);
setRadius(mRadius);
}
private void setColor(int color) {
mColor = color;
mPaint = new Paint();
mPaint.setColor(mColor);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setAntiAlias(true);
invalidate();
}
private void setRadius(float radius) {
mRadius = radius;
RectF r = new RectF(0, 0, 2 * mRadius, 2 * mRadius);
mPath = new Path();
mPath.moveTo(0,0);
mPath.lineTo(0, mRadius);
mPath.arcTo(r, 180, 90);
mPath.lineTo(0,0);
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
/*Paint paint = new Paint();
paint.setColor(Color.RED);
canvas.drawRect(0, 0, mRadius, mRadius, paint);*/
int w = getWidth();
int h = getHeight();
canvas.drawPath(mPath, mPaint);
canvas.save();
canvas.translate(w, 0);
canvas.rotate(90);
canvas.drawPath(mPath, mPaint);
canvas.restore();
canvas.save();
canvas.translate(w, h);
canvas.rotate(180);
canvas.drawPath(mPath, mPaint);
canvas.restore();
canvas.translate(0, h);
canvas.rotate(270);
canvas.drawPath(mPath, mPaint);
}
}