Bagaimana cara menggambar batas pada satu sisi tata letak linier?

186

Saya bisa menggambar perbatasan ke tata letak linier, tetapi semakin menarik di semua sisi. Saya ingin membatasi hanya ke sisi kanan, seperti yang Anda lakukan di CSS (border-right: 1px solid red;).

Saya sudah mencoba ini, tetapi masih menarik di semua sisi:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
    <shape android:shape="rectangle" >
        <stroke
            android:height="2dp"
            android:width="2dp"
            android:color="#FF0000" />

        <solid android:color="#000000" />

        <padding
            android:bottom="0dp"
            android:left="0dp"
            android:right="1dp"
            android:top="0dp" />

        <corners
            android:bottomLeftRadius="0dp"
            android:bottomRightRadius="5dp"
            android:radius="1dp"
            android:topLeftRadius="5dp"
            android:topRightRadius="0dp" />
    </shape>
</item>

Ada saran tentang cara mencapai ini?

BTW, saya tidak ingin menggunakan retasan menempatkan tampilan 1dp lebar di sisi yang diperlukan.

Nitin Bansal
sumber
Anda dapat menggunakan drawableLeft di tata letak Anda
njzk2

Jawaban:

359

Anda dapat menggunakan ini untuk mendapatkan perbatasan di satu sisi

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
    <shape android:shape="rectangle">
        <solid android:color="#FF0000" />
    </shape>
</item>
<item android:left="5dp">
    <shape android:shape="rectangle">
        <solid android:color="#000000" />
    </shape>
</item>
</layer-list>

Diedit

Karena banyak orang termasuk saya ingin memiliki perbatasan satu sisi dengan latar belakang transparan, saya telah menerapkan batas BorderDrawableyang dapat memberi saya perbatasan dengan ukuran dan warna yang berbeda dengan cara yang sama seperti kita menggunakan css. Tetapi ini tidak dapat digunakan melalui xml. Untuk mendukung XML, saya telah menambahkan BorderFrameLayoutdi mana tata letak Anda dapat dibungkus.

Lihat github saya untuk sumber lengkap.

Vivek Khandelwal
sumber
5
bagaimana jika Anda ingin warna berbasis alpha solid dengan batas bawah? Saya telah memikirkan solusi untuk itu dengan api XML Drawable Android tetapi saya tidak bisa mengetahuinya.
Mario Lenci
Ini tidak berhasil untuk saya - anehnya melakukan kebalikan dari apa yang saya inginkan warna yang lebih gelap di dalam, dengan gradien abu-abu yang saya overlay untuk asrama. Telah berpikir untuk membuat drawable rectangle pada ukuran tertentu untuk dijadikan drawableLeft pada item tersebut. Sepertinya ini tidak efisien.
jbenowitz
@ jbenowitz: Urutan item dalam daftar lapisan lebih penting. Jika Anda mundur maka Anda akan mendapatkan hasil itu.
Vivek Khandelwal
Saya telah memperbaiki ini dengan menambahkan goresan warna batas dan bentuk yang tersisa warna tombol. Itu berhasil.
jbenowitz
242

Mudah seperti pie, memungkinkan bg transparan:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <gradient
        android:angle="0"
        android:startColor="#f00"
        android:centerColor="@android:color/transparent"
        android:centerX="0.01" />
</shape>

Ubah sudut untuk mengubah lokasi perbatasan:

  • 0 = kiri
  • 90 = bawah
  • 180 = benar
  • 270 = atas
Oded Breiner
sumber
19
Sejauh ini, ini adalah jawaban terbaik di sini,
sayang
11
Bagus, namun saya tentu tidak akan menggambarkannya sebagai "semudah pie".
funkybro
7
Ini tidak berfungsi jika Anda membutuhkan batas yang lebih tebal atau jika Anda membutuhkan batas pada banyak sisi.
Prinsip holografik
1
@codeman - gunakan ini sebagai latar belakang untuk pandangan Anda, maka ia akan mewarisi tingginya.
Oded Breiner
2
bagaimana cara menyesuaikan stroke atau lebar perbatasan?
Ruturaj Patil
101

Anda juga dapat mengimplementasikan apa yang Anda inginkan menggunakan satu layer

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:bottom="-5dp"
        android:right="-5dp"
        android:top="-5dp">
        <shape android:shape="rectangle" >
            <solid android:color="@color/color_of_the_background" />

            <stroke
                android:width="5dp"
                android:color="@color/color_of_the_border" />
        </shape>
    </item>

</layer-list>

cara ini hanya batas kiri terlihat tetapi Anda dapat mencapai kombinasi yang Anda inginkan dengan bermain dengan bottom, left, rightdan topatribut dari itemelemen

Viktor Grekov
sumber
3
Ini jelas berguna ketika Anda memiliki warna latar belakang lain dan Anda ingin menindih bg yang dapat digambar ini dengan border. (y)
Aung Pyae
3
Apa yang saya butuhkan, tetapi apakah benar menggunakan bantalan negatif?
IlyaEremin
1
Ini solusi terbaik. Saya mengganggu apa yang dilakukan -5dp di sana.
Amit Kumar
1
Lapisan negatif umum dalam HTML / CSS. Ini hanya mendorong hal-hal ke arah lain. Dalam pengalaman saya, sepertinya itu juga berlaku di Android.
spaaarky21
Implementasi menggunakan margin negatif tidak berfungsi dengan baik jika tata letak Anda memiliki clipChildren = false atau clipToPadding = false. Jika demikian, Anda dapat menggunakan solusinya dengan dua persegi panjang yang tumpang tindih, seperti yang diusulkan oleh Vivek Khandelwal
Jesús Barrera
80

Untuk mendapatkan batas pada satu sisi yang dapat ditarik, terapkan sisi negatif insetpada 3 sisi lainnya (menyebabkan batas tersebut ditarik keluar dari layar).

<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:insetTop="-2dp" 
    android:insetBottom="-2dp"
    android:insetLeft="-2dp">

    <shape android:shape="rectangle">
        <stroke android:width="2dp" android:color="#FF0000" />
        <solid android:color="#000000" />
    </shape>

</inset>

masukkan deskripsi gambar di sini

Pendekatan ini mirip dengan jawaban naykah, tetapi tanpa menggunakan a layer-list.

polisi
sumber
4
Ini adalah jawaban terbaik IMO
James
jawaban yang sangat bagus, saya hanya perlu mengubah lebar dan inset menjadi 10dp :) Dan banyak lagi, saya perlu batas di sebelah kiri, jadi saya mengubah android: insetLeft ke android: insetRight. Sangat sederhana! Klik tombol Keeping Material: D
Phuong
Tepat seperti yang saya butuhkan, ubah insertXdi bagian atas untuk memutuskan batas yang akan ditampilkan dan yang tidak.
CularBytes
Saya bahkan dapat memiliki warna solid @null dan kemudian metode ini tidak menyebabkan overdraw. Jenius. Terima kasih!
Unknownweirdo
2
Perhatian: Ini akan menggeser konten tampilan Anda dan juga akan mengubah ukurannya. Gunakan dengan hati-hati.
vovahost
7

Sebagai alternatif (jika Anda tidak ingin menggunakan latar belakang), Anda dapat dengan mudah melakukannya dengan membuat tampilan sebagai berikut:

<View
    android:layout_width="2dp"
    android:layout_height="match_parent"
    android:background="#000000" />

Untuk memiliki batas kanan saja, letakkan ini setelah tata letak (tempat Anda ingin memiliki perbatasan):

<View
    android:layout_width="2dp"
    android:layout_height="match_parent"
    android:background="#000000" />

Untuk memiliki batas kiri saja, letakkan ini sebelum tata letak (tempat Anda ingin memiliki perbatasan):

Bekerja untuk saya ... Semoga ini bisa membantu ....

Nishant Jha
sumber
6

Saya dapat mencapai efek dengan kode berikut

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:left="0dp" android:right="-5dp" android:top="-5dp" android:bottom="-5dp">
        <shape
        android:shape="rectangle">
            <stroke android:width="1dp" android:color="#123456" />
        </shape>
    </item>
</layer-list>

Anda dapat menyesuaikan dengan kebutuhan Anda untuk posisi perbatasan dengan mengubah arah perpindahan

IvelinStanchev
sumber
5
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" >
        <shape>
            <solid
                android:color="#f28b24" />
            <stroke
                android:width="1dp"
                android:color="#f28b24" />
            <corners
                android:radius="0dp"/>
            <padding
                android:left="0dp"
                android:top="0dp"
                android:right="0dp"
                android:bottom="0dp" />
        </shape>
    </item>
    <item>
        <shape>
            <gradient
                android:startColor="#f28b24"
                android:endColor="#f28b24"
                android:angle="270" />
            <stroke
                android:width="0dp"
                android:color="#f28b24" />
            <corners
                android:bottomLeftRadius="8dp"
                android:bottomRightRadius="0dp"
                android:topLeftRadius="0dp"
                android:topRightRadius="0dp"/>
            <padding
                android:left="10dp"
                android:top="10dp"
                android:right="10dp"
                android:bottom="10dp" />
        </shape>
    </item>
</selector>
alejandrocordon
sumber
5

Contoh bagus lainnya contoh

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<inset xmlns:android="http://schemas.android.com/apk/res/android"
     android:insetRight="-2dp">

     <shape android:shape="rectangle">
         <corners
             android:bottomLeftRadius="4dp"
             android:bottomRightRadius="0dp"
             android:topLeftRadius="4dp"
             android:topRightRadius="0dp" />
         <stroke
             android:width="1dp"
             android:color="@color/nasty_green" />
         <solid android:color="@android:color/transparent" />
     </shape>

</inset>
Muklas
sumber
2

Tidak disebutkan tentang file sembilan-tambalan di sini. Ya, Anda harus membuat file, namun itu pekerjaan yang cukup mudah dan itu benar-benar " versi lintas dan mendukung transparansi " solusi. Jika file ditempatkan ke drawable-nodpidirektori, ia bekerja pxberdasarkan, dan dalam drawable-mdpikarya kira-kira sebagai basis dp (terima kasih untuk sampel ulang).

Contoh file untuk pertanyaan awal ( kanan-batas: 1px merah; ) ada di sini:

http://ge.tt/517ZIFC2/v/3?c

Cukup tempatkan ke drawable-nodpidirektori.

Quark
sumber
2

Batas warna yang berbeda. Saya menggunakan 3 item.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@color/colorAccent" />
        </shape>
    </item>
    <item android:top="3dp">
        <shape android:shape="rectangle">
            <solid android:color="@color/light_grey" />
        </shape>
    </item>
    <item
        android:bottom="1dp"
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape android:shape="rectangle">
            <solid android:color="@color/colorPrimary" />
        </shape>
    </item>
</layer-list>
Ritesh
sumber