Nét mở của Android?


93

Có thể tạo một đối tượng hình dạng Android chỉ với nét vẽ trên một số mặt nhất định không?

Ví dụ: tôi có:

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

Tương tự như CSS này:

border: 3px dashed black;

Làm cách nào để đặt nét vẽ chỉ ở một bên? Đây là cách tôi sẽ làm điều đó trong CSS:

border-left: 3px dashed black;

Làm cách nào để bạn thực hiện việc này trong Android XML?

Câu trả lời:


126

Tôi đã đạt được một giải pháp tốt với giải pháp này:

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

Điều này hoạt động tốt trong trường hợp bạn cần một nền trong suốt nhưng vẫn là một màu nét mở (Trong trường hợp của tôi, tôi chỉ cần một dòng dưới cùng). Nếu bạn cần màu nền, bạn có thể thêm màu hình khối như trong câu trả lời Maragues.

CHỈNH SỬA 1

Đôi khi, đối với các thiết bị Mật độ cao, việc sử dụng giá trị nhúng thấp có thể kết thúc bằng các nét hoặc khoảng cách rất mỏng hoặc không nhìn thấy được. Điều này cũng có thể xảy ra với bạn khi đặt bộ chia ListView.

Cách giải quyết đơn giản nhất là sử dụng khoảng cách 1px thay vì 1dp. Điều này sẽ làm cho đường luôn hiển thị ở mọi mật độ. Giải pháp tốt nhất sẽ là tạo tài nguyên thứ nguyên cho từng mật độ, để có được kích thước tốt nhất cho từng thiết bị.

Chỉnh sửa 2

Thật thú vị, nhưng tôi đã cố gắng sử dụng cái này 6 năm sau và tôi không thể nhận được kết quả tốt trên các thiết bị Lollipop.

Có lẽ giải pháp hiện tại là sử dụng 9-patch. Android lẽ ra đã có một giải pháp dễ dàng cho vấn đề này sau ngần ấy thời gian.


Điều này cũng làm việc cho tôi, nhưng tôi không biết chính xác tại sao tôi phải sử dụng -2dp thay vì -1dp. Nếu tôi sử dụng cái sau, tôi vẫn có thể thấy một đường mỏng.
Edu Zamora

1
@EduZamora vâng, có vẻ như đối với các thiết bị mật độ cao -1dp không hoạt động như mong đợi
htafoya

Tôi cũng nhận được đường viền cho tất cả các bên, nhưng không chỉ đường viền dưới cùng.
Cheok Yan Cheng

@YanChengCHEOK hãy thử với 1px thay vì 1dp.
htafoya

@htafoya đây là một giải pháp tuyệt vời. Cảm ơn!
abriggs

52

Tôi biết câu hỏi này đã được đăng từ lâu, vì vậy câu trả lời sẽ không được sử dụng bởi người đăng câu hỏi này, nhưng nó vẫn có thể giúp ích cho người khác.

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

Sử dụng insetthẻ và cung cấp giá trị âm cho đường viền bên mà bạn muốn xóa.

Các giá trị có thể là:

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


Vâng và đừng làm những gì tôi đã làm và hãy thử và đặt phần đính kèm trong thẻ đột quỵ mà không đọc phần còn lại của câu trả lời! (cảm ơn vì câu trả lời BTW OP. Giải pháp hoàn hảo)
Kiran

thanh lịch ! Tôi thích giải pháp này
Hao Qi

41

Tôi đã giải quyết vấn đề này bằng cách sử dụng lớp danh sách, kết hợp hai hình dạng, một trong số đó có chiều cao 1dp được đặt ở dưới cùng

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>

Sau đó, trong tệp 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"/>

Điều này lấp đầy khoảng trống giữa table_options và exit_bar bằng nền và ngay trước khi exit_bar in ra dòng 1dp. Đây là mẹo cho tôi, tôi hy vọng nó sẽ giúp ích cho người khác.

Đã chỉnh sửa câu trả lời để đặt các lớp theo đúng thứ tự. Thx Alex!


Có thể hữu ích nếu bạn không đăng câu trả lời nếu bạn thực sự muốn tự mình có câu trả lời. Khi các nhà phát triển khác thấy đã có câu trả lời (thay vào đó là câu trả lời thực sự là không), họ không có khuynh hướng trả lời.
MrSnowflake

31

Một người khác thực hiện các câu trả lời khác bằng cách sử dụng đệm. Đoạn mã nhỏ này tạo đường viền trên và dưới.

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

4
Đây là câu trả lời tốt nhất nếu bạn cần các góc bo tròn.
MacKinley Smith

Điều này cũng đã giúp tôi rất nhiều. Hãy dùng thử và ủng hộ
Boy

@ug_ Tôi nghĩ đây là cách tiếp cận tốt nhất. Hoạt động hoàn hảo, nhờ
Lalit Sharma

Làm. Có vẻ hoàn toàn sai trong ngăn xem trước của Android Studio (v1.1) nhưng trên thiết bị thì ổn.
Murat Ögat

26

Câu trả lời của @ Maragues là ngược lại, vì các bảng vẽ trong danh sách lớp kéo từ trên xuống dưới (có nghĩa là mục cuối cùng trong danh sách được vẽ ở trên cùng):

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

Thao tác này sẽ tô màu cho hình dạng một cách hiệu quả, sau đó vẽ màu nền lên trên nó, để lại 1dp cuối cùng rõ ràng cho màu đường hiển thị.


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>


2

Tôi đã sử dụng mã sau.

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