Як створити стандартні кнопки без полів (як у згаданому керівництві щодо дизайну)?


113

Я просто перевіряв рекомендації щодо дизайну і цікавився кнопкам без полів. Я погуглив і спробував знайти джерело, але сам не можу зібрати його. Це звичайний віджет Button, але ви додаєте користувацький (за замовчуванням Android) стиль? Як зробити ці кнопки без полів (звичайно, ви можете встановити фон порожнім, але тоді у мене немає дільника)?

Тут наведено посилання на інструкції з дизайну:

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


Відповіді:


163

Щоб усунути деяку плутанину:

Це робиться в два етапи: Встановлення атрибута фону кнопки на андроїд: attr / selectableItemBackground створює вам кнопку із зворотним зв'язком, але немає фону.

android:background="?android:attr/selectableItemBackground"

Рядок для розділення кнопки без полів від решти вашої компонування виконується поданням з фоном android: attr / delierVertical

android:background="?android:attr/dividerVertical"

Для кращого розуміння тут викладено макет комбінації кнопок OK / Скасувати без полів у нижній частині екрана (як на правому малюнку вгорі).

<RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:layout_alignParentBottom="true">
        <View
            android:layout_width="match_parent"
            android:layout_height="1dip"
            android:layout_marginLeft="4dip"
            android:layout_marginRight="4dip"
            android:background="?android:attr/dividerVertical"
            android:layout_alignParentTop="true"/>
        <View
            android:id="@+id/ViewColorPickerHelper"
            android:layout_width="1dip"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_alignParentBottom="true"
            android:layout_marginBottom="4dip"
            android:layout_marginTop="4dip"
            android:background="?android:attr/dividerVertical" 
            android:layout_centerHorizontal="true"/>
        <Button
            android:id="@+id/BtnColorPickerCancel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:layout_toLeftOf="@id/ViewColorPickerHelper"
            android:background="?android:attr/selectableItemBackground"
            android:text="@android:string/cancel" 
            android:layout_alignParentBottom="true"/>
        <Button
            android:id="@+id/BtnColorPickerOk"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_alignParentRight="true"
            android:layout_alignParentTop="true"
            android:background="?android:attr/selectableItemBackground"
            android:text="@android:string/ok" 
            android:layout_alignParentBottom="true" 
            android:layout_toRightOf="@id/ViewColorPickerHelper"/>
    </RelativeLayout>

25
Варто зазначити: це рішення працює лише для рівня 11+ API.

9
Якщо ви використовуєте HoloEverywhere, він працює для API рівня 7+. Ви повинні змінити ?android:attr/selectableItemBackgroundдля ?attr/selectableItemBackgroundі ?android:attr/dividerVerticalдля?attr/dividerVertical
Brais Габена

1
?android:attr/dividerVerticalforа ?attr/dividerVerticalтакож працює для abs
oscarthecat


22

Пізня відповідь, але багато поглядів. Оскільки API <11 ще не загинули, для тих, хто тут зацікавлений, є хитрістю.

Нехай ваш контейнер має потрібний колір (може бути прозорим). Потім надайте кнопкам селектор із прозорим кольором за замовчуванням та деяким кольором при натисканні. Таким чином у вас з’явиться прозора кнопка, але вона змінить колір при натисканні (як у голографічного). Ви також можете додати деяку анімацію (наприклад, холо). Селектор повинен бути приблизно таким:

res/drawable/selector_transparent_button.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" 
          android:exitFadeDuration="@android:integer/config_shortAnimTime">
     <item android:state_pressed="true"
         android:drawable="@color/blue" />

   <item android:drawable="@color/transparent" />
</selector>

І кнопка повинна мати android:background="@drawable/selector_transparent_button"

PS: дозвольте контейнеру мати роздільники ( android:divider='@android:drawable/...для API <11)

PS [Новачки]: вам слід визначити ці кольори у значеннях / кольорах.xml


Це прекрасно працювало і для, API Level 10і для API Level > 10!
theblang

Це краще, ніж робити це програмно, хоча і те, і інше працювало б.
Еран Голдін

1
Атрибут "exitFadeDuration" використовується лише в API рівня 11 і вище.
Бевор

так, приємний. Читачі вважають, що невідомі теги XML ігноруються, тож вони використовуватимуть затухання для api> = 11, а просто працюватимуть для <11
aacotroneo

18

Для тих, хто хоче кнопки без полів, але все ж анімований при натисканні. Додайте це у кнопку.

style="?android:attr/borderlessButtonStyle"

Якщо ви хотіли роздільник / лінію між ними. Додайте це в лінійний макет.

style="?android:buttonBarStyle"

Підсумок

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:orientation="horizontal"
   style="?android:buttonBarStyle">

    <Button
        android:id="@+id/add"
        android:layout_weight="1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/add_dialog" 
        style="?android:attr/borderlessButtonStyle"
        />

    <Button
        android:id="@+id/cancel"
        android:layout_weight="1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/cancel_dialog" 
        style="?android:attr/borderlessButtonStyle"
        />

</LinearLayout>

плюс для кнопкиBarStyle. і це відповідь btw.
frostymarvelous

7

Для стилю матеріалу додайте style="@style/Widget.AppCompat.Button.Borderless"під час використання бібліотеки AppCompat.


5

З джерела додатків на iosched я придумав цей ButtonBarклас:

/**
 * An extremely simple {@link LinearLayout} descendant that simply reverses the 
 * order of its child views on Android 4.0+. The reason for this is that on 
 * Android 4.0+, negative buttons should be shown to the left of positive buttons.
 */
public class ButtonBar extends LinearLayout {

    public ButtonBar(Context context) {
        super(context);
    }

    public ButtonBar(Context context, AttributeSet attributes) {
        super(context, attributes);
    }

    public ButtonBar(Context context, AttributeSet attributes, int def_style) {
        super(context, attributes, def_style);
    }

    @Override
    public View getChildAt(int index) {
        if (_has_ics)
            // Flip the buttons so that "OK | Cancel" becomes "Cancel | OK" on ICS
            return super.getChildAt(getChildCount() - 1 - index);

        return super.getChildAt(index);
    }

    private final static boolean _has_ics = Build.VERSION.SDK_INT >= 
                                        Build.VERSION_CODES.ICE_CREAM_SANDWICH;
}

Це буде те, LinearLayoutщо кнопки "ОК" і "Скасувати" переходять у режим, і вони оброблятимуть їх у відповідному порядку. Потім помістіть це в макет, на який потрібно кнопки:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:divider="?android:attr/dividerHorizontal"
          android:orientation="vertical"
          android:showDividers="middle">
    <!--- A view, this approach only works with a single view here -->
    <your.package.ButtonBar style="?android:attr/buttonBarStyle"
        android:id="@+id/buttons"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:weightSum="1.0">
        <Button style="?android:attr/buttonBarButtonStyle"
            android:id="@+id/ok_button"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="0.5"
            android:text="@string/ok_button" />
        <Button style="?android:attr/buttonBarButtonStyle"
            android:id="@+id/cancel_button"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="0.5"
            android:text="@string/cancel_button" />
    </your.package.ButtonBar>
</LinearLayout>

Це дає вигляд діалогового вікна з кнопками без полів. Ви можете знайти ці атрибути в res в рамках. buttonBarStyleробить вертикальний дільник і прокладку. buttonBarButtonStyleзадано як borderlessButtonStyleдля теми Holo, але я вважаю, що це має бути найбільш надійним способом її відображення, оскільки рамки хочуть її відображати.


як я міг би поставити це (? android: attr / buttonBarButtonStyle) у styles.xml як елемент стилю?
лисиць

4

Подивіться в тему атрибутів buttonBarStyle, buttonBarButtonStyleі borderlessButtonStyle.


Якщо я використовую, buttonBarButtonStyleя отримую виняток E/AndroidRuntime(17134): Caused by: java.lang.reflect.InvocationTargetException E/AndroidRuntime(17134): Caused by: android.content.res.Resources$NotFoundException: Resource is not a Drawable (color or path): TypedValue{t=0x1/d=0x1030281 a=2 r=0x1030281}Не маю поняття, чому, але з використанням selectableItemBackgroundчудес.
Хтось десь

4

Також ви можете робити кнопки без полів через код:

TypedValue value= new TypedValue();
getApplicationContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground, value, true);
 myButton.setBackgroundResource(value.resourceId);

Це працює, дякую. Але android.R.attr.selectableItemBackgroundпотрібен API 21. Будь-яка ідея, як це зробити на попередніх версіях?
arenaq

Не працює. Я намагаюся встановити ресурс android.R.attr.buttonBarButtonStyle, і він говорить, що ресурс неможливо знайти.
Крісті Валлійська

використовувати android.R.attr.selectableItemBackground
Ідж

2

Для тих, хто хоче створити кнопку без полів програмно для API> = 8

ImageButton smsImgBtn = new ImageButton(this);
//Sets a drawable as the content of this button
smsImgBtn.setImageResource(R.drawable.message_icon);    
//Set to 0 to remove the background or for bordeless button
smsImgBtn.setBackgroundResource(0);

Це краще, простіше, ніж рішення lsj. Просто встановітьBackgroundResource (0)
jk7

2

Ще одне рішення, яке повинно працювати як на старих, так і на новіших платформах Android - це використання

android:background="@android:color/transparent"

атрибут для подання кнопки. Але після додавання вищевказаної кнопки не надаватиме зворотного зв’язку з дотиком.

Для забезпечення зворотного зв'язку з дотиком додайте наступний код до класу діяльності

button.setOnTouchListener(new View.OnTouchListener() {          
    @Override
    public boolean onTouch(View view, MotionEvent event) {
        switch (event.getAction())
        {
            case MotionEvent.ACTION_DOWN:    
                ((Button)view).setBackgroundColor(Color.LTGRAY);
                break;
            case MotionEvent.ACTION_UP:
                ((Button)view).setBackgroundColor(Color.TRANSPARENT);
        }
        return false;
    }
});

Це працює добре для мене.


Я б додав case MotionEvent.ACTION_CANCEL: нижче case MotionEvent.ACTION_UP: , а також.
Медо

2

Для всіх, хто все ще шукає:

успадкуйте свій власний стиль для кнопок Holo:

<style name="yourStyle" parent="@android:style/Holo.ButtonBar">
  ...
</style>

або Holo Light:

<style name="yourStyle" parent="@android:style/Holo.Light.ButtonBar">
  ...
</style>

і для кнопок Holo без полів:

<style name="yourStyle" parent="@android:style/Widget.Holo.Button.Borderless.Small">
  ...
</style>

або Holo Light:

<style name="yourStyle" parent="@android:style/Widget.Holo.Light.Button.Borderless.Small">
  ...
</style>

2

Так ви створюєте програмну кнопку без полів (плоску) без використання XML

ContextThemeWrapper myContext = new ContextThemeWrapper(this.getActivity(), 
   R.style.Widget_AppCompat_Button_Borderless_Colored);

Button myButton = new Button(myContext, null, 
   R.style.Widget_AppCompat_Button_Borderless_Colored);

Я використовував: ContextThemeWrapper myContext = new ContextThemeWrapper(this.getActivity(), R.style.Widget_AppCompat_Button_Borderless_Colored); Button myButton = new Button(myContext); і це не буде працювати. Після додавання 2-го і 3-го параметра він працює!
levibostian

1

Використовуйте наведений нижче код у своєму XML-файлі. Використовуйте android: background = "# 00000000", щоб мати прозорий колір.

<Button
   android:id="@+id/btnLocation"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:background="#00000000"
   android:text="@string/menu_location"
   android:paddingRight="7dp"
/>

1

Ви можете користуватися бібліотекою підтримки AppCompat для кнопки без полів.

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

<Button
    style="@style/Widget.AppCompat.Button.Borderless"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="16dp" 
    android:text="@string/borderless_button"/>

Кольорову кнопку без полів можна зробити так:

<Button
    style="@style/Widget.AppCompat.Button.Borderless.Colored"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="16dp" 
    android:text="@string/borderless_colored_button"/>

0

Чомусь ні для мене, style="Widget.Holo.Button.Borderless"ні android:background="?android:attr/selectableItemBackground"для мене не працювало. Якщо бути точнішим, Widget.Holo.Button.Borderlessзробили роботу на Android 4.0, але не працювали на Android 2.3.3. Що було для мене хитрістю в обох версіях, android:background="@drawable/transparent"і це XML у res / dravable / transparent.xml:

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

Звичайна голова через підхід до стіни.


2
Налаштування фону на @android: кольоровий / прозорий працював для мене, без потреби в додатковому XML-файлі.
Ніколай Бух-Андерсен

Тут не вказується спосіб отримання дільника.
Наварр

3
@Navarr, відповідно до відповіді Блонделла, роздільник не є частиною "кнопки без полів". Також це не повинно бути через те, що кнопки та будь-який інший клас перегляду не повинні інформувати про оточуючі компоненти GUI. Це відповідальність контейнера. У коментарях до допису Блонделла є посилання на те, що, як видається, макет деталі контакту ICS. Існує додатковий вигляд (з ідентифікатором вертикальний_дівідер) для відображення дільника. Немає рішення про автоматичні роздільники, хоча є акуратний android:background="?android:attr/dividerVertical"трюк.
Імператор Оріоній

Питання ОП стосувалося Android UX "Безмежні кнопки", і в усіх прикладах вони мають роздільник - який, мабуть, є частиною кнопкиBarStyle. Хоча ви дали мені дуже корисну інформацію, дякую.
Наварр

0

Чудове слайд-шоу про те, як досягти бажаного ефекту від Googles Nick Butcher (початок із слайда 20). Він використовує стандартний андроїд @attrдля стилювання кнопки та дільника.


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

0

Додавши до верхньої відповіді, ви також можете використовувати подання з темно-сірим кольором тла в лінійному макеті.

<View
    android:layout_width="match_parent"
    android:layout_height="1dip"
    android:layout_marginBottom="4dip"
    android:layout_marginLeft="4dip"
    android:layout_marginRight="4dip"
    android:layout_marginTop="4dip"
    android:background="@android:color/darker_gray"/>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="4dip"
    android:orientation="horizontal"
    android:weightSum="1">

    <Button
        android:id="@+id/button_decline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_weight="0.50"
        android:background="?android:attr/selectableItemBackground"
        android:padding="10dip"
        android:text="@string/decline"/>

    <View
        android:layout_width="1dip"
        android:layout_height="match_parent"
        android:layout_marginLeft="4dip"
        android:layout_marginRight="4dip"
        android:background="@android:color/darker_gray"/>

    <Button
        android:id="@+id/button_accept"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="10dp"
        android:layout_weight="0.50"
        android:background="?android:attr/selectableItemBackground"
        android:padding="10dip"
        android:text="@string/accept"/>
</LinearLayout>

Якщо ваша лінія горизонтальна, ви хочете встановити висоту 1dip і ширину, щоб відповідати батьківській, і навпаки, якщо ваша лінія вертикальна.


0

Якщо ви хочете досягти того ж програмно:

(це C #, але легко перекладається на Java)

Button button = new Button(new ContextThemeWrapper(Context, Resource.Style.Widget_AppCompat_Button_Borderless_Colored), null, Resource.Style.Widget_AppCompat_Button_Borderless_Colored);

Матч

    <Button
       style="@style/Widget.AppCompat.Button.Borderless.Colored"
    .../>

0

Спробуйте цей код, щоб видалити фоновий рисунок (@ dravable / bg) програмно, просто нам потрібно вказати null як параметр.

Button btn= new Button(this);
btn.setText("HI");
btn.setBackground(null);

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