Как создать стандартные кнопки без полей (как в упомянутом руководстве по дизайну)?

114

Я просто проверял рекомендации по дизайну и задавался вопросом о кнопках без полей. Я вытаращил глаза и попытался найти в источнике, но не смог собрать его самостоятельно. Это обычный виджет Button, но вы добавляете собственный стиль (по умолчанию для Android)? Как сделать эти кнопки без полей (конечно, вы можете сделать фон пустым, но тогда у меня нет разделителя)?

Здесь ссылки на рекомендации по дизайну:

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

KarlKarlsom
источник
Похожий stackoverflow.com/questions/14046232/…
Халед Аннаджар,

Ответы:

163

Чтобы устранить некоторую путаницу:

Это делается в два шага: Установка атрибута фона кнопки на android: attr / selectableItemBackground создает кнопку с обратной связью, но без фона.

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

Линия, отделяющая кнопку без полей от остального макета, выполняется представлением с фоном android: attr / dividerVertical

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

Для лучшего понимания вот макет для комбинации кнопок ОК / Отмена без полей в нижней части экрана (как на правом рисунке выше).

<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>
KarlKarlsom
источник
25
Стоит отметить: это решение работает только для уровня API 11+.
9
Если вы используете HoloEverywhere, он работает для уровня API 7+. Вы должны переодеться ?android:attr/selectableItemBackgroundдля ?attr/selectableItemBackgroundи ?android:attr/dividerVerticalдля?attr/dividerVertical
Брайс Габен
1
?android:attr/dividerVerticalforа ?attr/dividerVerticalтакже работает для
пресса
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 [Новички]: вы должны определить эти цвета в values ​​/ colors.xml

аакотронео
источник
Это отлично сработало как для, так API Level 10и для API Level > 10!
theblang
Это лучше, чем делать это программно, хотя оба будут работать.
Эран Голдин
1
Атрибут exitFadeDuration используется только в API уровня 11 и выше.
Бевор,
ага @Bevor, милый. Читатели считают, что неизвестные теги 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>
aLIEz
источник
плюс для buttonBarStyle. и это ответ, кстати.
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>

Это дает вам вид диалога с кнопками без полей. Вы можете найти эти атрибуты в разрешении во фреймворке. buttonBarStyleделает вертикальный разделитель и отступ. buttonBarButtonStyleустановлен как borderlessButtonStyleдля темы Holo, но я считаю, что это должен быть наиболее надежный способ ее отображения, поскольку платформа хочет ее отображать.

Дандре Эллисон
источник
как я могу поместить это (? android: attr / buttonBarButtonStyle) в styles.xml как элемент стиля?
Lis
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творит чудеса.
Someone Somewhere
4

Вы также можете сделать кнопки без полей с помощью кода:

TypedValue value= new TypedValue();
getApplicationContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground, value, true);
 myButton.setBackgroundResource(value.resourceId);
ISJ
источник
Работает, спасибо. Но android.R.attr.selectableItemBackgroundтребует API 21. Есть идеи, как это сделать в более ранних версиях?
arenaq
Это не работает. Я пытаюсь установить ресурс android.R.attr.buttonBarButtonStyle, и он говорит, что ресурс не может быть найден.
Кристи Уэлш
используйте android.R.attr.selectableItemBackground
Isj 05
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);
Sohail
источник
Это лучше, проще, чем решение lsj. Просто setBackgroundResource (0)
jk7
2

Другое решение, которое должно работать как на старой, так и на новой платформе Android, - это использовать

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

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

Чтобы обеспечить обратную связь при касании, добавьте следующий код в класс Activity

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;
    }
});

Он отлично работает для меня.

prodev
источник
Я бы также добавил case MotionEvent.ACTION_CANCEL: ниже case MotionEvent.ACTION_UP: .
Medo
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>
silversmurf
источник
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);
Manuel
источник
Я использовал: ContextThemeWrapper myContext = new ContextThemeWrapper(this.getActivity(), R.style.Widget_AppCompat_Button_Borderless_Colored); Button myButton = new Button(myContext); и это не сработало. После добавления 2-го и 3-го параметра он работает!
levibostian 01
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 / drawable / transparent.xml:

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

Обычная голова через стену подход.

Император Орионии
источник
2
Установка фона на @android: color / transparent сработала для меня, без необходимости в дополнительном файле XML.
Николай Бух-Андерсен
Здесь не указано, как получить разделитель.
Navarr
3
@Navarr согласно ответу Бланделла, разделитель не является частью «кнопки без полей». И не должно быть, потому что кнопки и любой другой класс представления не должны быть информированы об окружающих компонентах графического интерфейса. Это ответственность контейнера. В комментариях к сообщению Бланделла есть ссылка на макет элемента контактной информации ICS. Есть дополнительный вид (с идентификатором vertical_divider) для отображения разделителя. Нет готового решения для автоматических разделителей, хотя есть одна android:background="?android:attr/dividerVertical"хитрость.
Emperor Orionii
Вопрос OP относится к Android UX «Кнопки без полей», и во всех примерах у них есть разделитель, который, по-видимому, является частью buttonBarStyle. Хотя вы дали мне очень полезную информацию, спасибо.
Navarr
0

Отличное слайд-шоу о том, как добиться желаемого эффекта от Googles Nick Butcher (начало со слайда 20). Он использует стандартный андроид @attrдля стилизации кнопки и разделителя.

Moritz
источник
Обратите внимание, что ответы только на ссылки не приветствуются, ответы SO должны быть конечной точкой поиска решения (по сравнению с еще одной остановкой ссылок, которые со временем устаревают). Пожалуйста, рассмотрите возможность добавления здесь отдельного синопсиса, сохранив ссылку в качестве справочной.
kleopatra
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

Попробуйте этот код, чтобы программно удалить фоновый рисунок (@ drawable / bg), просто нам нужно указать null в качестве параметра.

Button btn= new Button(this);
btn.setText("HI");
btn.setBackground(null);
Рамеш Кумар
источник
1
Спасибо за этот фрагмент кода, который может оказать некоторую немедленную помощь. Надлежащее объяснение будет значительно улучшить свою долгосрочную ценность, показывая , почему это является хорошим решением проблемы и сделает его более полезным для читателей будущих с другими подобными вопросами. Пожалуйста , измените свой ответ , чтобы добавить некоторые объяснения, в том числе допущений , которые вы сделали.
NOhs 04