Bagaimana cara membuat ListView dengan sudut bulat di Android?

176

Bagaimana cara membuat ListView dengan sudut bulat di Android?

Legenda
sumber
Pertanyaan ini sangat berguna, begitu juga jawaban Anda .. !!
Sajad Karuthedath

Jawaban:

371

Berikut adalah salah satu cara melakukannya (Terima kasih untuk Dokumentasi Android!):

Tambahkan berikut ini ke dalam file (katakan customshape.xml) dan kemudian tempatkan di (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> 

Setelah Anda selesai membuat file ini, cukup setel latar belakang di salah satu cara berikut:

Melalui Kode: listView.setBackgroundResource(R.drawable.customshape);

Melalui XML , cukup tambahkan atribut berikut ke wadah (mis: LinearLayout atau bidang apa pun):

android:background="@drawable/customshape"

Semoga seseorang menemukan itu berguna ...

Legenda
sumber
2
Terima kasih atas tipnya. Hanya FYI, salin-tempel memberi saya pengecualian runtime yang mengatakan, "XmlPullParserException: Tag file XML baris # 4 tag <gradient> membutuhkan atribut 'angle' menjadi kelipatan 45" .. Mudah diperbaiki dengan mengubah sudut ke 270.
allclaws
Terima kasih untuk perbaikannya ... Tapi saya tidak tahu mengapa itu bisa terjadi .. Apakah Anda menemukan alasan khusus?
Legenda
@teedyay: Kapan saja sobat :)
Legenda
1
sama seperti allclaws, sudut harus kelipatan 45: "XmlPullParserException: Binary XML file line # 4 tag <gradient> membutuhkan atribut 'angle' menjadi kelipatan 45"
Youssef
29
Itu tidak bekerja dengan baik dengan menyoroti pilihan: Ketika item atas atau bawah dipilih, latar belakang berwarna persegi panjang dan digambar di atas latar belakang bersudut bulat.
Kris Van Bael
56

Meskipun itu berhasil, ia mengeluarkan seluruh warna latar belakang juga. Saya sedang mencari cara untuk melakukan hanya perbatasan dan hanya mengganti kode tata letak XML dengan yang satu ini dan saya baik untuk pergi!

<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> 
Kevin Parker
sumber
Lihat juga jawaban ini
ThomasRS
12

@ kris-van-bael

Bagi mereka yang memiliki masalah dengan sorotan pemilihan untuk baris atas dan bawah di mana persegi panjang latar belakang muncul pada pilihan Anda perlu mengatur pemilih untuk tampilan daftar Anda ke warna transparan.

listView.setSelector(R.color.transparent);

Di color.xml cukup tambahkan yang berikut -

<color name="transparent">#00000000</color>
alvins
sumber
5
itu tidak berhasil untuk saya. Saya menambahkan baris berikut, namun, dan menghilangkannya:android:cacheColorHint="@android:color/transparent"
cesar
1
Ini pasti memperbaiki masalah pemilihan untuk saya - terima kasih! Anda juga dapat menggunakan android.R.color.transparent untuk warna Selector alih-alih membuatnya sendiri.
greg7gkb
3
Alih-alih melakukannya secara terprogram, tambahkan ini ke ListView Anda dalam tata letak XML untuk menyembunyikan warna pilihan: android: listSelector = "# 00000000"
Elad Nava
@alvins Apakah ada cara untuk membuat Layout dapat dipilih untuk menyoroti item tampilan daftar seperti?
Bharat Dodeja
apa yang harus saya lakukan jika saya ingin menggunakan warna buram untuk listSelector?
suitianshi
3

Jawaban lain sangat berguna, terima kasih kepada penulis!

Tapi saya tidak bisa melihat bagaimana mengkustomisasi persegi panjang saat menyorot item pada pilihan daripada menonaktifkan highlight @alvins @bharat dojeha.

Berikut ini berfungsi bagi saya untuk membuat wadah item tampilan daftar bulat tanpa garis besar dan abu-abu terang saat dipilih dengan bentuk yang sama:

Xml Anda perlu mengandung pemilih seperti misalnya (dalam 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>

Kemudian Anda perlu menerapkan daftar adaptor dan mengganti metode getView untuk mengatur pemilih kustom sebagai latar belakang

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        //snip
        convertView.setBackgroundResource(R.drawable.customshape);
        //snip
    }

dan perlu juga 'menyembunyikan' persegi panjang pemilih default misalnya di onCreate (saya juga menyembunyikan garis pembagi abu-abu tipis saya di antara item):

listView.setSelector(android.R.color.transparent);
listview.setDivider(null);

Pendekatan ini memecahkan solusi umum untuk drawables, tidak hanya ListViewItem dengan berbagai status pemilihan.

dr_g
sumber
3

Memperbarui

Solusinya hari ini adalah dengan menggunakan CardViewdengan dukungan untuk sudut bulat bawaan.


Jawaban asli *

Cara lain yang saya temukan adalah untuk menutupi tata letak Anda dengan menggambar gambar di atas tata letak. Mungkin membantu Anda. Lihat Android XML sudut terpotong bulat

Richard Le Mesurier
sumber
2

Namun solusi lain untuk seleksi menyoroti masalah dengan item pertama, dan terakhir dalam daftar:

Tambahkan padding ke atas dan bawah latar belakang daftar Anda sama dengan atau lebih besar dari jari-jari. Ini memastikan sorotan pemilihan tidak tumpang tindih dengan kurva sudut Anda.

Ini adalah solusi termudah ketika Anda membutuhkan penyorotan seleksi yang tidak transparan.

<?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>
William Morrison
sumber
1

Ini sangat berguna bagi saya. Saya ingin menyarankan solusi lain untuk menyorot dengan sempurna sudut-sudut membulat jika Anda menggunakan milik Anda sendiriCustomAdapter .

Mendefinisikan File XML

Pertama-tama, masuk ke dalam folder yang dapat digambar dan buat 4 bentuk berbeda:

  • shape_top

    <gradient
        android:startColor="#ffffff"
        android:endColor="#ffffff"
        android:angle="270"/>
    <corners
        android:topLeftRadius="10dp"
        android:topRightRadius="10dp"/>

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

Sekarang, buat tata letak baris yang berbeda untuk setiap bentuk, yaitu untuk shape_top:

  • Anda juga dapat melakukan ini dengan mengubah latar belakang secara terprogram.

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

Dan menentukan pemilih untuk setiap daftar berbentuk, yaitu untuk 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>

Ubah CustomAdapter Anda

Terakhir, tentukan opsi tata letak di dalam Anda 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);
}

Dan itu selesai!

Machado
sumber
1

untuk membuat border, Anda harus membuat file xml lain dengan properti solid dan sudut di folder drawable dan menyebutnya di latar belakang

pawan kumar
sumber
0

Saya menggunakan tampilan kustom yang saya tata letak di atas yang lain dan yang hanya menggambar 4 sudut kecil dengan warna yang sama dengan latar belakang. Ini berfungsi apa pun konten tampilan dan tidak mengalokasikan banyak memori.

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);
    }
}
mbonnin
sumber