Відкритий Android обведення?


94

Чи можна створити об’єкт фігури Android з обведенням лише на певних сторонах?

Наприклад, у мене є:

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

Що схоже на цей CSS:

border: 3px dashed black;

Як я можу встановити штрих лише з одного боку? Ось як я це зробив би в CSS:

border-left: 3px dashed black;

Як це зробити в Android XML?

Відповіді:


127

Я досяг хорошого рішення за допомогою цього:

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

Це добре працює, якщо вам потрібен прозорий фон, але все ще відкритий колір обведення (у моєму випадку мені знадобився лише нижній рядок). Якщо вам потрібен колір фону, ви можете додати однотонний колір форми, як у відповіді Мараґеса.

РЕДАГУВАТИ 1

Іноді для пристроїв високої щільності використання низьких значень занурення може закінчитися дуже тонкими або невидимими штрихами або відстанями. Це може трапитися з вами також при встановленні роздільників ListView.

Найпростішим обхідним шляхом є використання відстані 1px замість 1dp. Це зробить лінію завжди видимою при будь-якій щільності. Найкращим рішенням було б створити розмірні ресурси для кожної щільності, щоб отримати найкращий розмір для кожного пристрою.

Редагувати 2

Цікаво, але я спробував використати це через 6 років, і я не можу отримати хорошого результату на пристроях Lollipop.

Можливо, поточне рішення полягає у використанні 9-патчів. Після цього часу Android повинен був легко вирішити цю проблему.


Це також спрацювало для мене, але я не знаю точно, чому мені довелося використовувати -2dp замість -1dp. Якби я використав останнє, я все одно міг би побачити тонку лінію.
Edu Zamora

1
@EduZamora так, здається, для пристроїв з високою щільністю -1dp працює не так, як очікувалося
htafoya 01.03.12

Я також отримую кордон для всіх сторін, але не лише нижній кордон.
Cheok Yan Cheng

@YanChengCHEOK спробуйте 1px замість 1dp.
htafoya

@htafoya це чудове рішення. Дякую!
abriggs

52

Я знаю, що це запитання було давно опубліковано, тому особа, яка опублікувала це запитання, не використовуватиме відповідь, але воно все одно може допомогти іншим.

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

Використовуйте insetтег і вкажіть від’ємне значення бічної межі, яку потрібно видалити.

Можливі значення:

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


Так, і не робіть те, що я зробив, і спробуйте вставити вкладений attr в тег обведення, не читаючи решту відповіді! (дякую за відповідь BTW OP. Ідеальне рішення)
Кіран,

елегантний! Мені подобається це рішення
Хао Ци,

41

Я вирішив це за допомогою шару списку, поєднавши дві фігури, одна з яких висотою 1dp розміщена внизу

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>

Потім у файлі 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"/>

Який заповнює пробіл між table_options та exit_bar фоном і безпосередньо перед exit_bar друкує 1dp рядок. Це зробило для мене фокус, сподіваюся, це допоможе комусь іншому.

Відповідь відредаговано, щоб розмістити шари у правильному порядку. Thx Alex!


Можливо, не опублікувати відповідь, якщо ви дійсно хочете отримати відповідь самостійно. Коли інші розробники бачать, що відповідь уже є (хоча в цьому випадку це насправді не), вони не так схильні відповідати.
MrSnowflake

31

Інший погляд на інші відповіді, використовуючи замість цього відступ. Цей маленький фрагмент робить межу зверху та знизу.

<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
Це, безумовно, найкраща відповідь, якщо вам потрібні закруглені кути.
MacKinley Smith

Цей також мені надзвичайно допоміг. Будь ласка, спробуйте і проголосуйте
Хлопчик

@ug_ Я думаю, що це найкращий підхід. Працює ідеально, дякую
Lalit Sharma

Працює. Виглядає абсолютно неправильно на панелі попереднього перегляду Android Studio (v1.1), але на пристрої це нормально.
Мурат Огат,

26

Відповідь @ Maragues зворотна, оскільки малюнки списку шарів малюються зверху вниз (тобто останній елемент у списку намальований зверху):

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

Це ефективно заповнить фігуру кольором лінії, а потім намалюйте колір фону поверх неї, залишивши останні 1dp чіткими, щоб колір лінії просвічувався.


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

Я використав наступний код.

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

0

Простий та ефективний

Щоб мати прозорий вигляд і все, що знаходиться зовні, має накладення якогось кольору, ви можете створити подання, які інкапсулюють центральний вигляд, без зовнішніх виглядів, що наступають на центральний вигляд .

Таким чином ви уникнете наявності зовнішнього до макета малюваного, а ви матимете більше контролю над відстанями видів без необхідності виконувати обчислення під час виконання.

<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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.