Làm thế nào để vẽ đường viền trên một mặt của bố cục tuyến tính?


185

Tôi có thể vẽ đường viền cho bố cục tuyến tính, nhưng nó đang được vẽ ở tất cả các phía. Tôi muốn giới hạn nó chỉ ở phía bên phải, giống như bạn làm trong CSS (viền phải: 1px solid red;).

Tôi đã thử điều này, nhưng nó vẫn thu hút từ mọi phía:

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

Bất kỳ đề xuất về làm thế nào để thực hiện điều này?

BTW, tôi không muốn sử dụng hack để đặt chế độ xem chiều rộng 1dp ở phía bắt buộc.


bạn có thể sử dụng drawableLeft trong bố cục của mình
njzk2

Câu trả lời:


358

Bạn có thể sử dụng điều này để có được đường viền ở một bên

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

EDITED

Vì nhiều người bao gồm cả tôi muốn có đường viền một bên với nền trong suốt, tôi đã triển khai một BorderDrawableđường viền có thể cho tôi đường viền với kích thước và màu sắc khác nhau giống như cách chúng tôi sử dụng css. Nhưng điều này không thể được sử dụng qua xml. Để hỗ trợ XML, tôi đã thêm một BorderFrameLayoutbố cục có thể được bọc.

Xem github của tôi cho nguồn hoàn chỉnh.


5
Điều gì nếu bạn muốn một màu dựa trên alpha rắn với đường viền dưới cùng? Tôi đã suy nghĩ về một giải pháp cho điều đó với api XML có thể vẽ được của Android nhưng tôi không thể tìm ra nó.
Mario Lenci

Điều này không phù hợp với tôi - thật kỳ quặc đã làm ngược lại những gì tôi muốn có một màu tối hơn ở bên trong, với màu xám tôi phủ lên cho các tấm ván. Đã suy nghĩ về việc làm cho một hình chữ nhật có thể vẽ được ở một kích thước nhất định để đặt làm drawableLeft trên vật phẩm. Điều này dường như không được sắp xếp hợp lý.
jbenowitz

@jbenowitz: Thứ tự của mục trong danh sách lớp là quan trọng hơn. Nếu bạn đảo ngược thì bạn sẽ nhận được kết quả.
Vivek Khandelwal

Tôi đã sửa lỗi này bằng cách thêm một nét màu viền và hình dạng còn lại của màu nút. Điều đó đã lừa
jbenowitz

242

Dễ dàng như chiếc bánh, cho phép một bg trong suốt:

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

Thay đổi góc để thay đổi vị trí viền:

  • 0 = trái
  • 90 = đáy
  • 180 = đúng
  • 270 = đầu

19
Đây là câu trả lời hay nhất ở đây, quá tệ, nó không được đánh giá cao
mittelmania

11
Đẹp, tuy nhiên tôi chắc chắn sẽ không mô tả nó là "dễ như ăn bánh".
funkybro

7
Điều này không hoạt động nếu bạn cần viền dày hơn hoặc nếu bạn cần viền ở nhiều phía.
nguyên tắc ba chiều

1
@codeman - sử dụng điều này làm nền cho chế độ xem của bạn, sau đó nó sẽ kế thừa chiều cao của nó.
Oded Breiner

2
Làm thế nào để điều chỉnh đột quỵ hoặc chiều rộng đường viền?
Ruturaj Patil

101

cũng có thể thực hiện những gì bạn muốn bằng một lớp duy nhất

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

cách này chỉ viền trái có thể nhìn thấy nhưng bạn có thể đạt được bất kỳ kết hợp mà bạn muốn bằng cách chơi với bottom, left, righttopcác thuộc tính của các itemnguyên tố


3
Điều này chắc chắn hữu ích khi bạn có màu nền khác và bạn muốn phủ lớp bg có thể vẽ này với đường viền. (y)
Aung Pyae

3
Chính xác những gì tôi cần, nhưng nó có đúng để sử dụng paddings tiêu cực?
IlyaEremin

1
Đây là giải pháp tốt nhất. Tôi đang làm phiền những gì -5dp làm ở đó.
Amit Kumar

1
Đệm tiêu cực là phổ biến trong HTML / CSS. Nó chỉ đơn giản là đẩy mọi thứ theo hướng khác. Theo kinh nghiệm của tôi, nó có vẻ hoàn toàn hợp lệ trong Android.
spaaarky21

Việc triển khai sử dụng lề âm không hoạt động tốt nếu bố cục của bạn có clipChildren = false hoặc clipToPadding = false. Nếu đây là trường hợp, bạn có thể sử dụng giải pháp với hai hình chữ nhật chồng chéo, giống như đề xuất của Vivek Khandelwal
Jesús Barrera

79

Để có được một đường viền ở một bên của hình vẽ, hãy áp dụng âm insetcho 3 mặt còn lại (làm cho các đường viền đó được vẽ ngoài màn hình).

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

nhập mô tả hình ảnh ở đây

Cách tiếp cận này tương tự như câu trả lời của naykah, nhưng không sử dụng a layer-list.


4
Đây là câu trả lời hay nhất IMO
James

Câu trả lời rất hay, tôi chỉ cần thay đổi độ rộng và in thành 10dp :) Và hơn nữa, tôi cần viền bên trái, vì vậy tôi thay đổi android: insetLeft thành android: insetRight. Quá đơn giản! Giữ nút Vật liệu nhấp: D
Phương

Chính xác những gì tôi cần, thay đổi insertXở trên cùng để quyết định những gì biên giới sẽ hiển thị và những gì không.
CularBytes

Tôi thậm chí có thể có một màu đặc của @null và sau đó phương pháp này không gây ra tình trạng rút tiền. Thiên tài. Cảm ơn bạn!
Unknownweirdo

2
Chú ý: Điều này sẽ thay đổi nội dung của chế độ xem của bạn và cũng sẽ thay đổi kích thước của nó. Sử dụng cẩn thận.
vovahost

7

Thay thế (nếu bạn không muốn sử dụng nền), bạn có thể dễ dàng thực hiện bằng cách tạo chế độ xem như sau:

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

Để chỉ có đường viền bên phải, hãy đặt đường viền này sau bố cục (nơi bạn muốn có đường viền):

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

Để chỉ có đường viền bên trái, hãy đặt đường viền này trước bố cục (nơi bạn muốn có đường viền):

Làm việc cho tôi ... Hy vọng nó sẽ giúp tôi ....


6

Tôi đã có thể đạt được hiệu quả với đoạn mã sau

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

Bạn có thể điều chỉnh theo nhu cầu của mình cho vị trí biên bằng cách thay đổi hướng dịch chuyển


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>

4

Một ví dụ tuyệt vời khác thí dụ

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

2

Không có đề cập về các tập tin chín bản vá ở đây. Có, bạn phải tạo tệp, tuy nhiên công việc khá dễ dàng và đó thực sự là giải pháp " hỗ trợ phiên bản chéo và minh bạch ". Nếu tệp được đặt vào drawable-nodpithư mục, nó hoạt động pxdựa trên và trong các drawable-mdpitác phẩm xấp xỉ như cơ sở dp (nhờ lấy mẫu lại).

Tệp ví dụ cho câu hỏi ban đầu ( viền phải: 1px solid red; ) có ở đây:

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

Chỉ cần đặt nó vào drawable-nodpithư mục.


1

Biên giới của các màu sắc khác nhau. Tôi đã sử dụng 3 mục.

<?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>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.