如何在 Android 中创建带圆角的 ListView?
Posted
技术标签:
【中文标题】如何在 Android 中创建带圆角的 ListView?【英文标题】:How do I create a ListView with rounded corners in Android? 【发布时间】:2010-12-13 13:57:31 【问题描述】:【问题讨论】:
这个问题真的很有用,你的答案也很有用..!! 【参考方案1】:这是一种方法(感谢 android 文档!):
将以下内容添加到文件中(例如 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>
创建此文件后,只需通过以下方式之一设置背景:
通过代码:
listView.setBackgroundResource(R.drawable.customshape);
通过 XML,只需将以下属性添加到容器(例如:LinearLayout 或任何字段):
android:background="@drawable/customshape"
希望有人觉得它有用...
【讨论】:
感谢您的精彩提示。仅供参考,复制粘贴给了我一个运行时异常,说:“XmlPullParserException:二进制 XML 文件行 #4虽然这确实有效,但它也消除了整个背景颜色。我正在寻找一种只做边框的方法,然后用这个替换那个 XML 布局代码,我很高兴!
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke android: android:color="#FF00FF00" />
<padding android:left="7dp" android:top="7dp"
android:right="7dp" android:bottom="7dp" />
<corners android:radius="4dp" />
</shape>
【讨论】:
另请查看this answer【参考方案3】:@kris-van-bael
对于那些在选择时背景矩形显示的顶行和底行有选择突出显示的问题,您需要将列表视图的选择器设置为透明颜色。
listView.setSelector(R.color.transparent);
在 color.xml 中只需添加以下内容 -
<color name="transparent">#00000000</color>
【讨论】:
它对我不起作用。但是,我添加了以下行,它摆脱了它:android:cacheColorHint="@android:color/transparent"
这绝对为我解决了选择问题 - 谢谢!您也可以使用 android.R.color.transparent 作为选择器颜色,而不是自己创建。
不要以编程方式执行此操作,而是将其添加到 XML 布局中的 ListView 以隐藏选择颜色:android:listSelector="#00000000"
@alvins 有没有什么办法可以让 Layout 可选择以突出显示列表视图项?
如果我想为 listSelector 使用不透明的颜色该怎么办?【参考方案4】:
更新
目前的解决方案是使用支持内置圆角的CardView
。
原答案*
我发现的另一种方法是通过在布局顶部绘制图像来掩盖布局。它可能会帮助你。查看Android XML rounded clipped corners
【讨论】:
【参考方案5】:其他答案非常有用,感谢作者!
但是我看不到如何在选择时突出显示项目而不是禁用突出显示@alvins @bharat dojeha 时自定义矩形。
在选择相同的形状时,以下适用于ME以创建圆形列表视图项容器,其中没有大纲和较轻的灰色:
您的 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: 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: 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>
然后你需要实现一个列表适配器并重写getView方法将自定义选择器设置为背景
@Override
public View getView(int position, View convertView, ViewGroup parent)
//snip
convertView.setBackgroundResource(R.drawable.customshape);
//snip
并且还需要“隐藏”默认选择器矩形,例如在 onCreate 中(我还隐藏了项目之间的灰色细分隔线):
listView.setSelector(android.R.color.transparent);
listview.setDivider(null);
这种方法解决了drawables的通用解决方案,而不仅仅是具有各种选择状态的ListViewItem。
【讨论】:
【参考方案6】:另一种选择突出显示列表中第一个和最后一个项目问题的解决方案:
在列表背景的顶部和底部添加等于或大于半径的填充。这可确保选择突出显示不会与您的角曲线重叠。
当您需要不透明的选择突出显示时,这是最简单的解决方案。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<solid android:color="@color/listbg" />
<stroke
android:
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>
【讨论】:
【参考方案7】:实际上,我认为此链接描述了最佳解决方案:
http://blog.synyx.de/2011/11/android-listview-with-rounded-corners/
简而言之,它为顶部、中间和底部的项目使用不同的背景,这样顶部和底部的项目就会被舍入。
【讨论】:
【参考方案8】:这对我来说非常方便。如果您使用自己的CustomAdapter
,我想建议另一种解决方法来完美突出圆角。
定义 XML 文件
首先,进入你的drawable文件夹并创建4个不同的形状:
形状顶部
<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
:
您也可以通过编程方式更改背景。
<TextView
android:id="@+id/textView1"
android:layout_
android:layout_
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_
android:layout_
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" />
并为每个形状列表定义一个选择器,即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>
更改您的 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);
这就完成了!
【讨论】:
【参考方案9】:要制作边框,你必须在可绘制文件夹中创建另一个具有solid和corners属性的xml文件并在后台调用它
【讨论】:
【参考方案10】:我正在使用一个自定义视图,我将其布局在其他视图之上,并且只绘制与背景颜色相同的 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);
【讨论】:
【参考方案11】:有不同的方法来实现它。最新的方法是对每个 ListItem 组件使用 CardView。 以下是一些步骤。
-
创建布局资源文件;我们将其命名为“listitem.xml
复制并粘贴下面封闭的 Listitem.xml 布局正文。
为每个列表项数据创建 RowItem 类;稍后您将实例化它以为每个列表项分配值。检查下面的代码,RowItem.class。
创建自定义 ListAdapter;让我们将其命名为 ListAdapter.class,并为每个列表项扩展此(#1)列表项布局(检查第二个代码 sn-p 以了解此)
设置此适配器 (#3) 的方式与在列表视图所属的活动中设置默认适配器的方式相同。也许唯一的区别是您首先必须使用值实例化 RowItem 类并将 RowItem 对象添加到您的适配器,然后通知您的适配器数据已更改。
**listitem.xml**
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_
android:layout_
android:orientation="vertical">
<GridLayout
android:layout_
android:layout_
android:alignmentMode="alignMargins"
android:columnCount="1"
android:columnOrderPreserved="false"
android:rowCount="1">
<androidx.cardview.widget.CardView
android:layout_
android:layout_
android:layout_rowWeight="1"
android:layout_columnWeight="1"
android:layout_margin="6dp"
app:cardCornerRadius="8dp"
app:cardElevation="6dp">
<LinearLayout
android:layout_
android:layout_
android:orientation="horizontal">
<ImageView
android:id="@+id/sampleiconimageID"
android:layout_
android:layout_
android:padding="5dp"/>
<LinearLayout android:layout_
android:layout_
android:orientation="vertical">
<TextView
android:id="@+id/titleoflistview"
android:layout_
android:layout_
android:text="Main Heading"
android:textStyle="bold" />
<TextView
android:id="@+id/samplesubtitle"
android:layout_
android:layout_
android:text="Sub Heading"
/>
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
</GridLayout>
</LinearLayout>
RowItem.Class
public class RowItem
private String heading;
private String subHeading;
private int smallImageName;
private String datetime;
private int count;
public void setHeading( String theHeading )
this.heading = theHeading;
public String getHeading()
return this.heading;
public void setSubHeading( String theSubHeading )
this.subHeading = theSubHeading;
public String getSubHeading( )
return this.subHeading;
public void setSmallImageName(int smallName)
this.smallImageName = smallName;
public int getSmallImageName()
return this.smallImageName;
public void setDate(String datetime)
this.datetime = datetime;
public String getDate()
return this.datetime;
public void setCount(int count)
this.count = count;
public int getCount()
return this.count;
示例列表适配器
public class ListAdapter extends BaseAdapter
private ArrayList<RowItem> singleRow;
private LayoutInflater thisInflater;
public ListAdapter(Context context, ArrayList<RowItem> aRow)
this.singleRow = aRow;
thisInflater = ( LayoutInflater.from(context) );
@Override
public int getCount()
return singleRow.size();
@Override
public Object getItem(int position)
return singleRow.get( position );
@Override
public long getItemId(int position)
return position;
public View getView(int position, View view, ViewGroup parent)
if (view == null)
view = thisInflater.inflate( R.layout.mylist2, parent, false );
//set listview objects here
//example
TextView titleText = (TextView) view.findViewById(R.id.titleoflistview);
RowItem currentRow = (RowItem) getItem(position);
titleText.setText( currentRow.getHeading() );
return view;
// LayoutInflater inflater=.getLayoutInflater();
// View rowView=inflater.inflate(R.layout.mylist, null,true);
//
// titleText.setText(maintitle[position]);
// subtitleText.setText(subtitle[position]);
// return null;
;
【讨论】:
以上是关于如何在 Android 中创建带圆角的 ListView?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Swift 4 的 UIView 中创建带圆角的渐变边框