Stroke Android sisi terbuka?

94

Apakah mungkin membuat objek bentuk Android dengan guratan hanya pada sisi tertentu?

Misalnya saya punya:

<stroke 
 android:width="3dip" 
 android:color="#000000"
    android:dashWidth="10dip" 
    android:dashGap="6dip" />

Yang mirip dengan CSS ini:

border: 3px dashed black;

Bagaimana saya bisa mengatur pukulan hanya pada satu sisi? Beginilah cara saya melakukannya di CSS:

border-left: 3px dashed black;

Bagaimana Anda melakukan ini di Android XML?

Reed Morse
sumber

Jawaban:

127

Saya mencapai solusi yang bagus dengan yang ini:

<?xml version="1.0" encoding="utf-8"?>

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- This is the line -->
    <item android:top="-1dp" android:right="-1dp" android:left="-1dp">
      <shape>
            <solid android:color="@android:color/transparent" />
            <stroke android:width="1dp" android:color="#ffffff" />
      </shape>
    </item>

</layer-list>

Ini berfungsi dengan baik jika Anda membutuhkan latar belakang transparan tetapi masih warna guratan terbuka (Dalam kasus saya, saya hanya membutuhkan garis bawah). Jika Anda membutuhkan warna background Anda dapat menambahkan warna solid shape seperti pada jawaban Maragues.

EDIT 1

Terkadang, untuk perangkat Densitas Tinggi, penggunaan nilai penurunan rendah dapat berakhir dengan goresan atau jarak yang sangat tipis atau tidak terlihat. Ini mungkin terjadi pada Anda juga saat mengatur pemisah ListView.

Solusi paling sederhana adalah menggunakan jarak 1px, bukan 1dp. Ini akan membuat garis selalu terlihat pada semua kepadatan. Solusi terbaik adalah membuat sumber daya dimensi untuk setiap kepadatan, guna mendapatkan ukuran terbaik untuk setiap perangkat.

Edit 2

Menyenangkan, tetapi saya mencoba menggunakan ini 6 tahun kemudian dan saya tidak bisa mendapatkan hasil yang baik di perangkat Lollipop.

Mungkin solusi saat ini adalah menggunakan 9-patch. Android seharusnya membuat solusi mudah untuk masalah ini setelah sekian lama.

htafoya.dll
sumber
Ini juga berhasil untuk saya, tetapi saya tidak tahu persis mengapa saya harus menggunakan -2dp daripada -1dp. Jika saya menggunakan yang terakhir, saya masih bisa melihat garis tipis.
Edu Zamora
1
@EduZamora ya tampaknya untuk perangkat dengan kepadatan tinggi -1dp tidak berfungsi seperti yang diharapkan
htafoya
Saya juga mendapatkan batas untuk semua sisi, tetapi tidak hanya batas bawah.
Cheok Yan Cheng
@YanChengCHEOK coba dengan 1px, bukan 1dp.
htafoya
@ Htafoya ini adalah solusi yang brilian. Terima kasih!
abriggs
52

Saya tahu pertanyaan ini sudah lama diposting, jadi jawabannya tidak akan digunakan oleh orang yang memposting pertanyaan ini, tetapi mungkin masih membantu orang lain.

 <?xml version="1.0" encoding="UTF-8"?>
    <!-- inset is used to remove border from top, it can remove border from any other side-->
    <inset xmlns:android="http://schemas.android.com/apk/res/android"
        android:insetTop="-2dp"
        >
    <shape xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/rectangle">
        <stroke android:width="1dp" android:color="#b7b7b7" />
        <corners android:bottomRightRadius="5dp"  android:bottomLeftRadius="5dp"/>

        <solid android:color="#454444"/>
    </shape>
    </inset>

Menggunakan inset tag dan berikan nilai negatif untuk tepi samping yang ingin Anda hapus.

Nilai yang mungkin adalah:

android:insetTop="-1dp" android:insetBottom="-1dp" android:insetLeft="-1dp" android:insetRight="-1dp"

Nirmal Dhara
sumber
Ya dan jangan lakukan apa yang saya lakukan dan coba dan letakkan inset attr di tag goresan tanpa membaca sisa jawabannya! (terima kasih atas jawabannya BTW OP. Solusi sempurna)
Kiran
elegan! Saya suka solusi ini
Hao Qi
41

Saya menyelesaikan ini dengan menggunakan lapisan daftar, menggabungkan dua bentuk, salah satunya dengan tinggi 1dp ditempatkan di bagian bawah

optionscreen_bottomrectangle.xml:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- This is the line -->
<item>
      <shape>
            <solid android:color="#535353" />
      </shape>
</item>
<!-- This is the main color -->
<item android:bottom="1dp">
     <shape>
           <solid android:color="#252525" />
     </shape>
</item>
</layer-list>

Kemudian, di file layout / main.xml

<TextView
    android:id="@+id/bottom_rectangle"
    android:background="@drawable/optionscreen_bottomrectangle"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:layout_below="@id/table_options"
    android:layout_above="@id/exit_bar"/>

Yang mengisi celah antara table_options dan exit_bar dengan latar belakang dan sebelum exit_bar mencetak baris 1dp. Ini melakukan trik untuk saya, saya harap ini membantu orang lain.

Jawaban diedit untuk menempatkan lapisan dalam urutan yang benar. Terima kasih Alex!

Maragues
sumber
Mungkin berguna untuk tidak memposting jawaban jika Anda benar-benar ingin memiliki jawaban sendiri. Ketika developer lain melihat bahwa sudah ada jawaban (meskipun dalam kasus ini sebenarnya tidak), mereka tidak cenderung untuk menjawab.
MrSnowflake
31

Yang lain mengambil tanggapan lain dengan menggunakan padding. Penembak jitu kecil ini membuat batas di atas dan bawah.

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- This is the line -->
    <item>
          <shape>
                <padding android:left="0dp" android:top="1dp" android:right="0dp" android:bottom="1dp"/>
                <solid android:color="#898989" />
          </shape>
    </item>
    <!-- This is the main color -->
    <item>
         <shape>
             <solid android:color="#ffffff" />
         </shape>
    </item>
</layer-list>
ug_
sumber
4
Sejauh ini, ini adalah jawaban terbaik jika Anda membutuhkan sudut membulat.
MacKinley Smith
Yang ini juga sangat membantu saya. Silakan mencobanya dan beri suara positif
Boy
@ug. Saya pikir ini adalah pendekatan terbaik. Bekerja dengan sempurna, terima kasih
Lalit Sharma
Bekerja. Terlihat sepenuhnya salah di panel pratinjau Android Studio (v1.1) tetapi pada perangkat tidak apa-apa.
Murat Ögat
26

@ Jawaban Maragues adalah mundur, karena daftar lapisan drawable menggambar dari atas ke bawah (artinya item terakhir dalam daftar digambar di atas):

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- This is the line -->
<item>
      <shape>
            <solid android:color="#535353" />
      </shape>
</item>
<!-- This is the main color -->
<item android:bottom="1dp">
     <shape>
           <solid android:color="#252525" />
     </shape>
</item>

</layer-list>

Ini akan secara efektif mengisi bentuk dengan warna garis, lalu menggambar warna latar belakang di atasnya, membiarkan 1 dp terakhir jelas agar warna garis terlihat.

Alex Pretzlav
sumber
2
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >


<item>
    <shape android:shape="rectangle" >
        <stroke  android:width="2dp"
                 android:color="#BBBBBB" />
        <solid android:color="@android:color/transparent" />
    </shape>
</item>
<item  android:bottom="2dp" >
    <shape android:shape="rectangle" >
        <stroke  android:width="2dp"
                 android:color="@color/main_background_color" />
        <solid android:color="@android:color/transparent" />
    </shape>
</item>

cerah
sumber
2

Saya telah menggunakan kode berikut.

<?xml version="1.0" encoding="UTF-8"?>
<!-- inset is used to remove border from top, it can remove border from any other side-->
<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:insetTop="-2dp" android:insetLeft="-2dp" android:insetRight="-2dp"
    >
    <shape xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/rectangle">
        <stroke android:width="1dp" android:color="@color/colorPrimary" />
        <solid android:color="#0000"/>
        <padding android:left="2dp" android:top="2dp" android:bottom="2dp" android:right="2dp"/>
    </shape>
</inset>
Ken W.
sumber
0

Sederhana dan efisien

Untuk mendapatkan tampilan transparan dan segala sesuatu di luar memiliki hamparan beberapa warna, yang dapat Anda lakukan adalah membangun tampilan yang merangkum tampilan tengah tanpa tampilan luar menginjak tampilan tengah. .

Dengan cara ini Anda menghindari drawable eksternal ke tata letak dan Anda memiliki kontrol lebih besar atas jarak tampilan tanpa harus melakukan penghitungan saat runtime.

<androidx.constraintlayout.widget.ConstraintLayout .. >

    <View
        android:id="@+id/center"
        android:layout_width="100dp"
        android:layout_height="100dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        android:background="@color/transparent"/>

   <View
        android:id="@+id/left_overlay"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/center"
        app:layout_constraintTop_toBottomOf="@id/top_overlay"
        app:layout_constraintBottom_toTopOf="@id/bottom_overlay"
        android:background="@color/black"
        android:alpha="0.5"
        />

    <View
        android:id="@+id/right_overlay"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintLeft_toRightOf="@id/center"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/top_overlay"
        app:layout_constraintBottom_toTopOf="@id/bottom_overlay"
        android:background="@color/black"
        android:alpha="0.5"
        />

    <View
        android:id="@+id/top_overlay"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@id/center"
        android:background="@color/black"
        android:alpha="0.5"
        />

    <View
        android:id="@+id/bottom_overlay"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/center"
        android:background="@color/black"
        android:alpha="0.5"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

GL

Braian Coronel
sumber