如何在Android中创建带有圆角的ListView?


Answers:


371

这是一种实现方法(不过感谢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"

希望有人觉得它有用...


2
感谢您的宝贵建议。仅供参考,复制粘贴给了我一个运行时异常说:“XmlPullParserException:二进制XML文件中的行#4 <梯度>标签需要‘角’属性为45的倍数” ..容易通过改变角度270补救
allclaws 2010年

感谢您的修复...但是我不知道为什么会这样。您找到任何具体的原因了吗?
传奇

@teedyay:随时朋友:)
传奇

1
与allclaws相同,角度应为45的倍数:“ XmlPullParserException:二进制XML文件第4行<gradient>标记要求'angle'属性为45的倍数”
Youssef

29
但是,它不适用于选择突出显示:选择顶部或底部项目时,其彩色背景为矩形,并绘制在圆角背景的顶部。
克里斯·范·贝尔

56

尽管这样做确实可行,但它也消除了整个背景色。我一直在寻找一种方法来制作边框,并用该边框替换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> 

同时查看此答案
ThomasRS 2012年

12

@ kris-van-bael

对于那些在选择时遇到问题的人,请在顶部和底部显示突出显示的背景矩形,您需要将列表视图的选择器设置为透明颜色。

listView.setSelector(R.color.transparent);

在color.xml中,只需添加以下内容-

<color name="transparent">#00000000</color>

5
它对我不起作用。但是,我添加了以下行,并删除了该行:android:cacheColorHint="@android:color/transparent"
cesar 2012年

1
这绝对为我解决了选择问题-谢谢!您还可以使用android.R.color.transparent作为选择器颜色,而不用创建自己的颜色。
greg7gkb 2012年

3
与其以编程方式进行操作,不如将其添加到XML布局中的ListView中以隐藏选择颜色:android:listSelector =“#00000000”
Elad Nava

@alvins有什么方法可以使Layout选择为高亮显示,例如列表视图项?
Bharat Dodeja 2013年

如果我想为listSelector使用不透明的颜色怎么办?
suitianshi

3

感谢作者,其他答案非常有用!

但是我看不到如何在选择时突出显示项目时自定义矩形,而不是禁用突出显示@alvins @bharat dojeha。

以下对我有用的方法是创建一个没有轮廓的圆形列表视图项容器,并且在选择相同形状时会显示一个浅灰色:

您的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>

然后,您需要实现一个列表适配器并覆盖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);

这种方法解决了可绘制对象的一般解决方案,而不仅仅是具有各种选择状态的ListViewItem。



2

选择的另一种解决方案突出显示了列表中第一项和最后一项的问题:

在列表背景的顶部和底部添加等于或大于半径的填充。这样可以确保选择突出显示不会与拐角曲线重叠。

当您需要非透明选择突出显示时,这是最简单的解决方案。

<?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>


1

这对我来说非常方便。我想建议另一个解决方法,如果您使用自己的方法,可以完美地突出显示圆角CustomAdapter

定义XML文件

首先,进入您的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

  • 您也可以通过编程方式更改背景。

    <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" />

并为每个形状列表定义一个选择器,即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);
}

这样就完成了!


1

要制作边框,您必须在drawable文件夹中制作另一个具有solid和corners属性的xml文件,并在后台调用它


0

我使用的是自定义视图,该视图在其他视图之上进行布局,并且仅以与背景相同的颜色绘制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);
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.