Як створити ListView із закругленими кутами в Android?


Відповіді:


371

Ось один із способів зробити це (хоча завдяки Документації на Android!):

Додайте наступне у файл (скажімо, carhape.xml), а потім помістіть його у нього (res / dravable / 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
Дякую за чудову пораду. Просто FYI, вставлення копії дало мені виключення під час виконання: "XmlPullParserException: Бінарний файл файлу XML №4 <градієнт> тег вимагає, щоб атрибут" кут "був кратним 45". Легко виправити, змінивши кут на 270.
allclaws

Дякую за виправлення ... Але я не знаю, чому це могло статися .. Ви знайшли якусь конкретну причину?
Легенда

@teedyay: У будь-який момент товариш :)
Легенда

1
так само, як у всіх класах, кут повинен бути кратним 45: "XmlPullParserException: Бінарний рядок файлу XML №4 <градієнт> тег вимагає, щоб атрибут '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

12

@ kris-van-bael

Для тих, хто має проблеми з виділенням виділення для верхнього та нижнього рядків, де фоновий прямокутник відображається під час вибору, потрібно встановити селектор для перегляду списку на прозорий колір.

listView.setSelector(R.color.transparent);

У color.xml просто додайте наступне -

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

5
це не працювало для мене. Я додав наступний рядок, і він позбувся його:android:cacheColorHint="@android:color/transparent"
Сезар

1
Це безумовно вирішило питання відбору для мене - дякую! Ви також можете використовувати android.R.color.transparent для кольору Selector замість створення власного.
greg7gkb

3
Замість того, щоб робити це програмно, додайте це до свого списку ListView у макеті XML, щоб приховати колір вибору: android: listSelector = "# 00000000"
Elad Nava

@alvins Чи є спосіб зробити макет обраним для виділення, як елемент перегляду списку?
Бхарат Додея

що мені робити, якщо я хочу використовувати непрозорий колір для 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 з різними станами вибору.


3

Оновлення

Рішенням сьогодні є використання CardViewопори для вбудованих закруглених кутів.


Оригінальна відповідь *

Ще один спосіб, який я знайшов, - замаскувати ваш макет, намалювавши зображення у верхній частині макета. Це може вам допомогти. Перегляньте закруглені кути Android XML


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-файлів

Перш за все, увійдіть у свою папку, що малюється, і створіть 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

щоб зробити кордон u, треба зробити ще один 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);
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.