如何创建标准的无边界按钮(如上述设计指南中所述)?


113

我只是查看设计指南,想知道无边界按钮。我凝视了一下,试图在源中查找,但我自己无法将其组合在一起。这是普通的Button小部件,但是您添加了自定义(Android默认)样式?如何制作这些无边界按钮(当然您可以将背景设置为空,但是我没有分隔线)?

这里链接到设计指南:

在此处输入图片说明


Answers:


163

为了消除一些混乱:

这需要2个步骤:将button background属性设置为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>

25
值得指出的是:此解决方案仅适用于API级别11+。

9
如果您使用HoloEverywhere,则适用于API级别7+。您必须更改?android:attr/selectableItemBackground?attr/selectableItemBackground?android:attr/dividerVertical?attr/dividerVertical
Brais加宾

1
?android:attr/dividerVerticalfor并且?attr/dividerVertical也适用于腹肌
oscarthecat


22

答案很晚,但是观点很多。由于<11的API尚未失效,对于那些对此感兴趣的人来说是个窍门。

让您的容器具有所需的颜色(可以是透明的)。然后为您的按钮提供一个选择器,使其具有默认的透明颜色,并在按下时具有某种颜色。这样,您将拥有一个透明的按钮,但是在按下时会更改颜色(如全息)。您还可以添加一些动画(例如全息)。选择器应该是这样的:

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

即使两者都可以工作,这总比以编程方式执行更好。
伊兰·高丁

1
属性“ exitFadeDuration”仅在API级别11和更高级别中使用。
Bevor 2015年

是的@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>

再加上buttonBarStyle。这就是答案。
frostymarvelous 2015年

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

4

看入主题属性buttonBarStylebuttonBarButtonStyleborderlessButtonStyle


如果使用,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奇迹。
某处某人2014年

4

您也可以通过代码使按钮无边界:

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

很好,谢谢。但是android.R.attr.selectableItemBackground需要API21。任何想法如何在早期版本中执行此操作?
arenaq '16

没用 我试图设置android.R.attr.buttonBarButtonStyle的资源,它说找不到该资源。
克里斯蒂·威尔士,

使用android.R.attr.selectableItemBackground
Isj 2013年

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的解决方案更好,更简单。只需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;
    }
});

它对我来说很好。


我还要在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); 它不起作用。添加第二个和第三个参数后,它就可以工作了!
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",对我来说,成功的窍门是res / drawable / transparent.xml中的XML:

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

普通头穿过墙。


2
将背景设置为@android:color / transparent对我有用,不需要额外的XML文件。
Nicolai Buch-Andersen

这没有包括如何获得分隔线。
纳瓦拉

3
根据Blundell的回答,@ Navarr表示,分隔线不是“无边框按钮”的一部分。也不应该是因为不应向按钮和任何其他视图类通知周围的GUI组件。那是容器的责任。在对Blundell帖子的评论中,有一个指向ICS联系人详细信息布局的链接。还有一个额外的视图(带有vertical_divider id)用于显示分隔线。尽管有一个巧妙的android:background="?android:attr/dividerVertical"技巧,但没有针对自动分频器的开箱即用解决方案。
Orionii皇帝

OP的问题是指Android UX的“无边框按钮”,在所有示例中,它们都有分隔线-显然是buttonBarStyle的一部分。尽管您给了我一些非常有用的信息,但还是谢谢您。
Navarr 2012年


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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.