Wie erstelle ich randlose Standardschaltflächen (wie in der genannten Designrichtlinie)?


113

Ich habe nur die Designrichtlinien überprüft und mich über die randlosen Knöpfe gewundert. Ich habe geglotzt und versucht, in der Quelle zu finden, kann es aber nicht alleine zusammenbringen. Ist dies das normale Button-Widget, aber Sie fügen einen benutzerdefinierten Stil (Android-Standard) hinzu? Wie mache ich diese randlosen Schaltflächen (natürlich kannst du den Hintergrund leer setzen, aber dann habe ich keinen Teiler)?

Hier Links zu den Designrichtlinien:

Geben Sie hier die Bildbeschreibung ein


Antworten:


163

Um Verwirrung zu beseitigen:

Dies erfolgt in zwei Schritten: Wenn Sie das Hintergrundattribut für Schaltflächen auf Android setzen: attr / selectableItemBackground erstellt eine Schaltfläche mit Feedback, jedoch ohne Hintergrund.

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

Die Linie, um die randlose Schaltfläche vom Rest Ihres Layouts zu trennen, wird durch eine Ansicht mit dem Hintergrund android: attr / dividerVertical erstellt

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

Zum besseren Verständnis finden Sie hier ein Layout für eine randlose Tastenkombination OK / Abbrechen am unteren Bildschirmrand (wie im rechten Bild oben).

<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
Hervorzuheben ist: Diese Lösung funktioniert nur für API Level 11+.

9
Wenn Sie HoloEverywhere verwenden, funktioniert es für API Level 7+. Sie müssen ?android:attr/selectableItemBackgroundfür ?attr/selectableItemBackgroundund ?android:attr/dividerVerticalfür?attr/dividerVertical
Brais Gabin

1
?android:attr/dividerVerticalforund ?attr/dividerVerticalarbeitet auch für abs
oscarthecat


22

Späte Antwort, aber viele Ansichten. Da APIs <11 noch nicht tot sind, ist dies für Interessierte ein Trick.

Lassen Sie Ihren Behälter die gewünschte Farbe haben (möglicherweise transparent). Geben Sie Ihren Schaltflächen dann einen Selektor mit standardmäßiger transparenter Farbe und etwas Farbe, wenn Sie gedrückt werden. Auf diese Weise haben Sie einen transparenten Knopf, der jedoch beim Drücken die Farbe ändert (wie bei Holos). Sie können auch Animationen hinzufügen (wie Holos). Der Selektor sollte ungefähr so ​​aussehen:

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>

Und der Knopf sollte haben android:background="@drawable/selector_transparent_button"

PS: Lassen Sie Ihren Container die Teiler haben ( android:divider='@android:drawable/...für API <11)

PS [Neulinge]: Sie sollten diese Farben in values ​​/ color.xml definieren


Dies funktionierte perfekt für beide API Level 10und API Level > 10!
Theblang

Dies ist besser als programmgesteuert, obwohl beide funktionieren würden.
Eran Goldin

1
Das Attribut "exitFadeDuration" wird nur in API Level 11 und höher verwendet.
Bevor

yep @Bevor, nett. Leser denken, dass unbekannte XML-Tags ignoriert werden, so dass Fading für API> = 11 verwendet wird und nur für <11
Aacotroneo

18

Für diejenigen, die randlose Schaltflächen möchten, aber beim Klicken immer noch animiert sind. Fügen Sie dies in die Schaltfläche ein.

style="?android:attr/borderlessButtonStyle"

Wenn Sie einen Teiler / eine Linie zwischen ihnen wollten. Fügen Sie dies im linearen Layout hinzu.

style="?android:buttonBarStyle"

Zusammenfassung

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

Plus für buttonBarStyle. und das ist übrigens die Antwort.
frostymarvelous

7

style="@style/Widget.AppCompat.Button.Borderless"Fügen Sie für den Materialstil hinzu, wenn Sie die AppCompat-Bibliothek verwenden.


5

Aus der iosched-App-Quelle habe ich mir diese ButtonBarKlasse ausgedacht :

/**
 * 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;
}

Dies ist der LinearLayoutPunkt, an dem die Schaltflächen "OK" und "Abbrechen" angezeigt werden und die in der richtigen Reihenfolge angeordnet werden. Fügen Sie dies dann in das Layout ein, in dem sich die Schaltflächen befinden sollen:

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

Dies gibt Ihnen das Aussehen des Dialogs mit randlosen Schaltflächen. Sie finden diese Attribute in der res im Framework. buttonBarStylemacht den vertikalen Teiler und die Polsterung. buttonBarButtonStyleist wie borderlessButtonStylefür das Holo-Thema festgelegt, aber ich glaube, dies sollte die robusteste Art sein, es anzuzeigen, da das Framework es anzeigen möchte.


Wie könnte ich dies (? android: attr / buttonBarButtonStyle) in styles.xml als Element eines Stils einfügen?
lis

4

Blick in die Themenattribute buttonBarStyle, buttonBarButtonStyleund borderlessButtonStyle.


Wenn ich benutze, buttonBarButtonStylebekomme ich eine Ausnahme. 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}Keine Ahnung warum, aber die Verwendung selectableItemBackgroundwirkt Wunder.
Jemand irgendwo

4

Sie können Schaltflächen auch durch Code randlos machen:

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

Es funktioniert, danke. Benötigt android.R.attr.selectableItemBackgroundaber API 21. Irgendeine Idee, wie dies in früheren Versionen gemacht werden soll?
Arenaq

Es funktioniert nicht. Ich versuche, die Ressource von android.R.attr.buttonBarButtonStyle festzulegen, und es heißt, dass die Ressource nicht gefunden werden kann.
Kristy Welsh

benutze android.R.attr.selectableItemBackground
Isj

2

Für diejenigen, die programmlos randlose Schaltflächen für APIs> = 8 erstellen möchten

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

Dies ist besser und einfacher als die Lösung von lsj. Setzen Sie einfachBackgroundResource (0)
jk7

2

Eine andere Lösung, die sowohl auf älteren als auch auf neueren Android-Plattformen funktionieren sollte, ist die Verwendung

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

Attribut für die Schaltflächenansicht. Nach dem Hinzufügen der obigen Zeile gibt die Schaltfläche jedoch kein Touch-Feedback.

Fügen Sie der Aktivitätsklasse den folgenden Code hinzu, um Touch-Feedback zu geben

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

Es funktioniert gut für mich.


Ich würde auch case MotionEvent.ACTION_CANCEL: unten hinzufügen case MotionEvent.ACTION_UP: .
Medo

2

Für alle, die noch suchen:

Erben Sie Ihren eigenen Stil für Holo-Schaltflächen:

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

oder Holo Light:

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

und für randlose Holo-Knöpfe:

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

oder Holo Light:

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

2

Auf diese Weise erstellen Sie programmgesteuert eine randlose (flache) Schaltfläche, ohne XML zu verwenden

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

Ich benutzte: ContextThemeWrapper myContext = new ContextThemeWrapper(this.getActivity(), R.style.Widget_AppCompat_Button_Borderless_Colored); Button myButton = new Button(myContext); und es würde nicht funktionieren. Nach dem Hinzufügen des 2. und 3. Parameters funktioniert es!
Levibostian

1

Verwenden Sie den folgenden Code in Ihrer XML-Datei. Verwenden Sie android: background = "# 00000000", um die transparente Farbe zu erhalten.

<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

Sie können die AppCompat-Unterstützungsbibliothek für die randlose Schaltfläche verwenden .

Sie können einen randlosen Button wie folgt erstellen:

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

Sie können den randlosen farbigen Knopf folgendermaßen erstellen:

<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

Aus irgendeinem Grund weder style="Widget.Holo.Button.Borderless"noch android:background="?android:attr/selectableItemBackground"für mich gearbeitet. Genauer gesagt, Widget.Holo.Button.Borderlesshat die Arbeit unter Android 4.0 erledigt, aber unter Android 2.3.3 nicht funktioniert. Was war der Trick für mich bei beiden Versionen android:background="@drawable/transparent"und dieser XML in res / drawable / transparent.xml:

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

Einfacher Kopf durch die Wand Annäherung.


2
Das Einstellen des Hintergrunds auf @android: color / transparent hat bei mir funktioniert, ohne dass eine zusätzliche XML-Datei erforderlich war.
Nicolai Buch-Andersen

Dies beinhaltet nicht, wie der Teiler erhalten wird.
Navarr

3
@Navarr Laut der Antwort von Blundell ist der Teiler kein Teil des "randlosen Knopfes". Dies sollte auch nicht daran liegen, dass Schaltflächen und andere Ansichtsklassen nicht über umgebende GUI-Komponenten informiert werden sollten. Das liegt in der Verantwortung des Containers. In den Kommentaren zu Blundells Beitrag befindet sich ein Link zu dem scheinbar ICS-Layout für Kontaktdetailelemente. Es gibt eine zusätzliche Ansicht (mit der ID vertikal_Divider) zum Anzeigen des Teilers. Keine Out-of-the-Box-Lösung für automatische Teiler, obwohl es einen ordentlichen android:background="?android:attr/dividerVertical"Trick gibt.
Kaiser Orionii

OPs Frage bezog sich auf die Android UX "Borderless Buttons", und in allen Beispielen haben sie den Teiler - der anscheinend Teil von buttonBarStyle ist. Obwohl Sie mir einige sehr hilfreiche Informationen gegeben haben, danke.
Navarr

0

Eine großartige Diashow, wie Sie mit Googles Nick Butcher den gewünschten Effekt erzielen (ab Folie 20). Er verwendet das Standard-Android @attr, um den Knopf und den Teiler zu stylen.


Beachten Sie, dass von Antworten nur mit Links abgeraten wird. SO-Antworten sollten der Endpunkt einer Suche nach einer Lösung sein (im Gegensatz zu einem weiteren Zwischenstopp von Referenzen, die im Laufe der Zeit veralten). Bitte fügen Sie hier eine eigenständige Zusammenfassung hinzu, wobei Sie den Link als Referenz behalten.
Kleopatra

0

Wenn Sie die oberste Antwort hinzufügen, können Sie auch Ansichten mit einer dunkelgrauen Hintergrundfarbe in einem linearen Layout wie diesem verwenden.

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

Wenn Ihre Linie horizontal ist, sollten Sie die Höhe auf 1 Dip und die Breite so einstellen, dass sie mit der übergeordneten Linie übereinstimmt, und umgekehrt, wenn Ihre Linie vertikal ist.


0

Wenn Sie dasselbe programmgesteuert erreichen möchten:

(Dies ist C #, aber leicht auf Java übertragbar.)

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

Spiel

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

0

Versuchen Sie diesen Code, um den Hintergrund (@ drawable / bg) programmgesteuert zu entfernen. Sie müssen lediglich null als Parameter angeben.

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

1
Vielen Dank für dieses Code-Snippet, das möglicherweise nur begrenzte und sofortige Hilfe bietet. Eine richtige Erklärung würde ihren langfristigen Wert erheblich verbessern, indem sie zeigt, warum dies eine gute Lösung für das Problem ist, und es für zukünftige Leser mit anderen, ähnlichen Fragen nützlicher machen. Bitte bearbeiten Sie Ihre Antwort, um eine Erklärung hinzuzufügen, einschließlich der von Ihnen getroffenen Annahmen.
NOhs
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.