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


407

У мене TextView, і я хотів би додати чорну облямівку уздовж верхньої та нижньої меж. Я спробував додати android:drawableTopі android:drawableBottomTextView, але це призвело лише до того, що весь перегляд став чорним.

<TextView
    android:background="@android:color/green"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:drawableTop="@android:color/black"
    android:drawableBottom="@android:color/black"
    android:text="la la la" />

Чи є спосіб легко додати верхню та нижню межі до перегляду (зокрема, TextView) в Android?


2
Дивно, що ніхто не згадав дільникВертикаль ! Це річ, створена Android для досягнення вертикальних дільниць. Холодно не бути простіше, і ви все робите на панелі WYSIWYG "Дизайн" в Android Studio.
Fattie

Примітка роздільникVertical був реалізований в API 11.
JPM

1
Можливо, ви можете показати, як використовувати роздільник Вертикальний?
androidguy

Відповіді:


430

В Android 2.2 ви можете зробити наступне.

Створіть XML-графічний рисунок, такий як /res/dravable/textlines.xml, і призначте його як фонове властивість TextView.

<TextView
android:text="My text with lines above and below"
android:background="@drawable/textlines"
/>

/res/dravable/textlines.xml

<?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:width="1dp" android:color="#FF000000" />
            <solid android:color="#FFDDDDDD" />

        </shape>
   </item>

   <item android:top="1dp" android:bottom="1dp"> 
      <shape 
        android:shape="rectangle">
            <stroke android:width="1dp" android:color="#FFDDDDDD" />
            <solid android:color="#00000000" />
        </shape>
   </item>

</layer-list>

Суть до цього полягає в тому, що вам потрібно вказати непрозорий колір фону, оскільки прозорі плівки не працюватимуть. (Принаймні, я думав, що вони це зробили, але я помилявся). У наведеному вище прикладі ви бачите, що суцільний колір першої форми #FFdddddd скопійований у колір обведення 2-ї форми.


11
Також дивіться рішення, яке також працює для TextViews, якщо ви хочете кордон навколо: stackoverflow.com/questions/3263611 / ...
emmby

26
Спробуйте використовувати, android:color="@null"щоб уникнути непрозорої фонової проблеми.
Метт Брайансон

@emmby: під час тестування цього коду на планшеті потрібен час для візуалізації на екрані. Через 1 секунду межі відображаються, коли я прокручую
Четан,

5
Трюк android: color = "@ null" не зробив для мене хитрості для збереження прозорості та просто відображення рамки з одного боку зору. Відповідь користувача1051892 нижче виконала роботу!
Рік Пастор

8
Це рішення також зробило межу зліва та справа - хоч і тонше.
AlikElzin-kilaka

279

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

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

            <solid android:color="#00FFFFFF" />

            <padding android:left="10dp"
                android:right="10dp"
                android:top="10dp"
                android:bottom="10dp" />
        </shape>
    </item>

</layer-list>

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

1
Дуже приємний трюк, хоча це може бути і приємніше, якщо нам не доведеться обманювати комп’ютер, щоб все зробити.
Юкіо Фукузава

прекрасно зроблено! на що слід звернути увагу - предмет ліворуч, зверху, праворуч, знизу має - (ширина штриха) dp
asakura89

Не показав жодної межі - просто зробив мій вміст перегляду меншим :(
AlikElzin-kilaka

1
Чудово зроблено, працював з прозорим фоном. Випробувано в 2.2 та 4.4.2. Потрібно охопити всіх між ними :)
HumaN

97

Варіант 1: Форма малювання

Це найпростіший варіант, якщо вам потрібно встановити рамку навколо макета або виду, в якому можна встановити фон. Створіть XML-файл у drawableпапці, який виглядає приблизно так:

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

    <solid android:color="#8fff93" />

    <stroke
        android:width="1px"
        android:color="#000" />

</shape>

Ви можете видалити, solidякщо не хочете заливку. Набір background="@drawable/your_shape_drawable"на вашому макеті / перегляді.

Варіант 2: Перегляд фону

Ось невеликий трюк, який я використав у RelativeLayout. В основному у вас є чорний квадрат під поданим видом, який ви хочете надати облямівці, а потім надайте цьому виду деяку підкладку (а не поле!), Щоб чорний квадрат показав по краях.

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

<View
    android:id="@+id/border"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignBottom="@+id/image"
    android:layout_alignLeft="@+id/image"
    android:layout_alignRight="@+id/image"
    android:layout_alignTop="@+id/main_image"
    android:background="#000" />

<ImageView
    android:id="@+id/image"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_...
    android:padding="1px"
    android:src="@drawable/..." />

Якщо вам цікаво, що робить роботу з adjustViewBounds=true. Однак це не працює, якщо ви хочете мати фон в цілому RelativeLayout, тому що існує помилка, яка зупиняє заповнення RelativeLayoutа View. У такому випадку я б рекомендував Shapeмалювати.

Варіант 3: 9-патч

Остаточним варіантом є використання 9-латового малювання, подібного до цього:

Ви можете використовувати його в будь-якому вікні, де ви можете встановити android:background="@drawable/...". І так, це має бути 6x6 - я спробував 5x5, і це не вийшло.

Недоліком цього методу є те, що ви не можете змінити кольори дуже легко, але якщо ви хочете вигадливих облямівок (наприклад, лише рамки вгорі та внизу, як у цьому питанні), ви, можливо, не зможете їх виконати з Shapeмалюнком , який не дуже потужний.

Варіант 4: Додаткові перегляди

Я забув згадати цей дійсно простий варіант, якщо ви хочете лише межі над і нижче вашого погляду. Ви можете розмістити свій погляд у вертикалі LinearLayout(якщо його ще немає), а потім додати порожні Views над і під ним так:

<View android:background="#000" android:layout_width="match_parent" android:layout_height="1px"/>

4
9 патч і форма, що малюється, добре, але я б рекомендував не додавати перегляди чи перегляди зображень для вирішення такої проблеми. Причина полягає в тому, що вам слід видалити стільки таких <елементів> зі своїх макетів, щоб покращити перемальовування макетів та анімацію. Я знімаю їх відразу та впроваджую щось подібне до варіанту 1 або 2.
Еміль

2
@Emile Це правда, але якщо ви використовуєте користувальницький ListView, який не підтримує роздільники, простий перегляд чудово. Ефект від продуктивності знаходиться поруч із нульовим показником, особливо якщо ви впевнені, що глибина макета буде знижена. Він також обходить помилки з роздільниками ListView на різних пристроях (я бачив деякі пристрої, які ігнорують цю властивість).
Том

Ви також можете використовувати ефективний шаблон переглядача з переглядами списку, щоб гарантувати зменшення кількості викликів для пошукуViewByID, що часто є причиною поганої продуктивності списку.
Еміль

В iOS у вас є лише один спосіб зробити це. На андроїд ви повинні перевірити щонайменше чотири, у моєму випадку варіант 4 - це шлях. Іноді траси, як фон висить, щоб відобразити, пам’ятайте про це.
Ратата Тата

1
Чому андроїд не мав найпростішого рішення для таких речей? як і на іншій мові, наприклад, HTML, CSS чи щось JavaFX, WPF ......
Асиф Муштак

95

Щоб додати а 1dp білу облямівку лише внизу та мати прозорий фон, ви можете скористатися наступним, що простіше, ніж більшість відповідей тут.

Для TextViewабо іншого виду додайте:

android:background="@drawable/borderbottom"

І в drawableкаталог додайте наступний XML, який називаєтьсяborderbottom.xml

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

Якщо ви хочете облямівку вгорі, змініть android:top="-2dp"наandroid:bottom="-2dp"

Колір не повинен бути білим, а також фон не повинен бути прозорим.

solidМоже не бути необхідним елементом. Це залежатиме від вашого дизайну (дякую В. Калюжню).

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


8
Це найкраще рішення, оскільки воно не створює перевищення, як інші
Грег Енніс

Чи є причина, що негативні позиції вдвічі більше, ніж інсульт з ( -2dpпроти 1dp)? Здається, працює, коли вони рівні за кількістю ( -1і 1).
Денис Княжев

@DenisKniazhev: При використанні -2dpрезультат був завжди чистим. Я думаю, був тестовий випадок, коли результат був не чистим. Я не можу пригадати, чи це був екран низької чи високої щільності чи навіть старіша версія Android (можливо, 2.x).
Тигр

Цікаво. Чи знаєте ви, чи це загальний випадок, наприклад, якщо я використовую 4dpдля ширини штриха, чи повинен я використовувати -8dpдля позиціонування?
Денис Княжев

1
@DenisKniazhev: (з пам’яті) це виглядало як обчислення з плаваючою комою, яке було трохи до великого чи малого. Це означає, що значенням -5dpбуде все, що потрібно зі значенням ширини 4pd. Це просто потрібно було трохи більше, щоб подолати неточність плаваючої величини.
Тигр

36

На даний момент прийнята відповідь не працює. Це створює тонкі вертикальні межі з лівої та правої сторони зору в результаті антизшивання.

Ця версія працює чудово. Це також дозволяє самостійно встановлювати ширину меж, а також ви можете додати рамки з лівої / правої сторони, якщо хочете. Єдиний недолік - це те, що НЕ підтримує прозорість.

Створіть XML, який можна назвати /res/drawable/top_bottom_borders.xmlз кодом нижче, та призначте його як фонове властивість TextView.

<?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="#DDDD00" /> <!-- border color -->
        </shape>
    </item>

    <item
        android:bottom="1dp" 
        android:top="1dp">   <!-- adjust borders width here -->
        <shape android:shape="rectangle">
            <solid android:color="#FFFFFF" />  <!-- background color -->
        </shape>
    </item>
</layer-list>

Тестовано на Android KitKat через Marshmallow


Як зробити всередині прозорим?
Хітеш Саху

1
@HiteshSahu Я думаю, що недоліком цього є те, що вам доведеться співставити фон макета з фоном віджета тут
chntgomez

35

Тому я хотів зробити дещо інше: межу в нижній частині ТІЛЬКИ, щоб імітувати подільник ListView. Я змінив відповідь Piet Delport і отримав таке:

<?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/background_trans_light" />    

        </shape>
   </item>

    <!-- this mess is what we have to do to get a bottom border only. -->
   <item android:top="-2dp"
         android:left="-2dp"
         android:right="-2dp"
         android:bottom="1px"> 
      <shape 
        android:shape="rectangle">    
            <stroke android:width="1dp" android:color="@color/background_trans_mid" />
            <solid android:color="@null" />
        </shape>
   </item>

</layer-list>

Зауважте, що використовуйте px замість dp, щоб отримати рівно 1 піксельний дільник (деякі DPI-телефони телефону змусять 1dp рядок зникнути).


2
шановний! яка цінність "@color/background_trans_light"?
Shajeel Afzal

Привіт @phreakhead, це насправді працює для мене! Ні верхньої, ні лівої, ні правої межі. Саме те, що мені було потрібно, дякую!
shanehoban

2
Чи можете ви пояснити, чому, коли ви ставите -2dp, він зникає, а коли ставите -1dp, він все ще видно? Дякую!
Франциско Ромеро,

9

Як сказав @Nic Hubbard, існує дуже простий спосіб додати межу.

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

Ви можете змінити висоту та колір тла на будь-який бажаючий.


8

Мої відповіді ґрунтуються на версії @Emile, але я використовую прозорий колір замість твердого.
Цей приклад намалює нижню межу 2dp.

<?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:width="2dp"
                     android:color="#50C0E9" />
            <solid android:color="@android:color/transparent" />
        </shape>
    </item>
    <item  android:bottom="2dp" >
        <shape android:shape="rectangle" >
            <stroke  android:width="2dp"
                     android:color="@color/bgcolor" />
            <solid android:color="@android:color/transparent" />
        </shape>
    </item>
</layer-list>

@ колір / bgcolor - це колір фону, на якому ви малюєте свій погляд з межею.

Якщо ви хочете змінити положення кордону, змініть зміщення за допомогою одного з:

android:bottom="2dp"
android:top="2dp"
android:right="2dp"
android:left="2dp"

або об'єднайте їх, щоб вони мали дві або більше меж:

android:bottom="2dp" android:top="2dp"

7

Ви також можете загорнути вигляд у FrameLayout, потім встановити колір тла кадру та накладки на те, що вам потрібно; однак перегляд тексту за замовчуванням має «прозорий» фон, тому вам також потрібно буде змінити колір тла перегляду тексту.


Досить просто. Ви керуєте розміром та напрямком обрисів за межами внутрішнього виду. Дякую.
Скотт Біггс

5

Чому б просто не створити високий перегляд 1dp з кольором фону? Тоді його можна легко розмістити там, де ви хочете.


4

Просто додати моє рішення до списку ..

Мені хотілося напівпрозорої нижньої межі, яка простягається повз початкову форму (Отже, напівпрозора межа була поза батьківським прямокутником).

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
  <item>
    <shape android:shape="rectangle" >      
      <solid android:color="#33000000" /> <!-- Border colour -->
    </shape>
  </item>
  <item  android:bottom="2dp" >
    <shape android:shape="rectangle" >     
      <solid android:color="#164586" />
    </shape>
  </item>
</layer-list>

Що дає мені;

введіть тут опис зображення


4

Щоб змінити це:

<TextView
    android:text="My text"
    android:background="@drawable/top_bottom_border"/>

Я віддаю перевагу такому підходу в "dravable / top_bottom_border.xml":

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape>
            <gradient
                android:angle="270"
                android:startColor="#000"
                android:centerColor="@android:color/transparent"
                android:centerX="0.01" />
        </shape>
    </item>
    <item>
        <shape>
            <gradient
                android:angle="90"
                android:startColor="#000"
                android:centerColor="@android:color/transparent"
                android:centerX="0.01" />
        </shape>
    </item>
</layer-list>

Це робить лише межі, а не прямокутник, який з’явиться, якщо ваш фон має колір.


3

Спочатку зробіть файл XML із вмістом, показаним нижче, та назви його border.xml та помістіть його у папку макета всередині каталогу res

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <stroke android:width="1dp" android:color="#0000" />
    <padding android:left="0dp" android:top="1dp" android:right="0dp"
        android:bottom="1dp" />
</shape>

Після цього всередині коду використовуйте

TextView tv = (TextView)findElementById(R.id.yourTextView);
tv.setBackgroundResource(R.layout.border);

Це зробить чорну лінію вгорі та внизу TextView.


Так, це буде працювати, я перевірив. Кнопка кнопки = (Кнопка) findViewById (R.id.button); button.setBackgroundResource (R.layout.border);
Нікіл Дінеш

У наведеному вище файлі XML я використав чорний колір, колір тла може бути чорним, спробуйте скористатися іншим кольором. Він обов'язково спрацює <? Xml version = "1.0" encoding = "UTF-8"?> < Shape xmlns: android = " schemas.android.com/apk/res/android "> <твердий android: color = "# 474848 "/> <інсульт android: width =" 1dp "android: color =" # ffff00 "/> <padding android: left =" 1dp "android: top =" 1dp "android: right =" 1dp "android: bottom =" 1dp "/> </shape>
Нікхіл Дінеш

1
Не працювало для мене. Лінія кордону була намальована посередині текстового виду - горизонтально.
AlikElzin-kilaka

3

Запишіть нижче коду

<View
    android:layout_width="wrap_content"
    android:layout_height="2dip"
    android:layout_below="@+id/topics_text"
    android:layout_marginTop="7dp"
    android:layout_margin="10dp"
    android:background="#ffffff" />

2

Ось спосіб її досягти.

    <?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:width="1dp"
                    android:color="@color/grey_coaching_text" />
            </shape>
        </item>

        <item
            android:bottom="1dp"
            android:top="1dp">
            <shape android:shape="rectangle">
                <solid android:color="@color/white" />
            </shape>
        </item>
    </layer-list>

Перший елемент для обведення та другий для твердого фону. Приховування лівої та правої меж.


2

Найпростіший спосіб додавання меж для вставки меж, використовуючи InsetDrawableнаступний, буде показано лише верхню межу:

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

        <solid android:color="@color/light_gray" />
        <stroke
            android:width=".5dp"
            android:color="@color/dark_gray" />
    </shape>
</inset>

2

Додайте файл до res / dravable

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

Додати посилання на цей файл до фонового ресурсу


1

Спробуйте обернути зображення лінійним шаром, і встановіть його фоном на колір облямівки, який потрібно навколо тексту. Потім встановіть прокладку на текстовому перегляді такою товщиною, яку потрібно для вашої межі.


1

Ви також можете використовувати 9-шлях для виконання своєї роботи. Створіть його так, щоб кольоровий піксель не розмножувався по висоті, а лише прозорим пікселем.


1
<shape xmlns:android="http://schemas.android.com/apk/res/android">

<solid android:color="@color/light_grey1" />
<stroke
    android:width="1dip"
    android:color="@color/light_grey1" />

<corners
    android:bottomLeftRadius="0dp"
    android:bottomRightRadius="0dp"
    android:topLeftRadius="5dp"
    android:topRightRadius="5dp" />

    </shape>

1

Просто додайте Перегляди вгорі та внизу View

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="@color/your_color"
        app:layout_constraintBottom_toTopOf="@+id/textView"
        app:layout_constraintEnd_toEndOf="@+id/textView"
        app:layout_constraintStart_toStartOf="@+id/textView" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:gravity="center"
        android:text="Testing"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="@color/your_color"
        app:layout_constraintEnd_toEndOf="@+id/textView"
        app:layout_constraintStart_toStartOf="@+id/textView"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

</android.support.constraint.ConstraintLayout>

0
// Just simply add border around the image view or view

<ImageView
                android:id="@+id/imageView2"
                android:layout_width="90dp"
                android:layout_height="70dp"
                android:layout_centerVertical="true"
                android:layout_marginRight="10dp"
                android:layout_toLeftOf="@+id/imageView1"
                android:background="@android:color/white"
                android:padding="5dip" />

// After that dynamically put color into your view or image view object

objView.setBackgroundColor(Color.GREEN);

//VinodJ/Abhishek

-1
<TextView
    android:id="@+id/textView3"
    android:layout_width="match_parent"
    android:layout_height="2dp"
    android:background="#72cdf4"
    android:text=" aa" />

Просто додайте цей TextView під текстом, де потрібно додати межу


-1

Просто для виконання відповідей @phreakhead і користувача1051892 , <item android:bottom|android:left|android:right|android:top>якщо вони негативні, повинно бути більше, ніж <stroke android:width>. Якщо ні, картина предмета буде змішана з малюванням штриха, і ви можете подумати, що ці значення не працюють.

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