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

KarlKarlsom
quelle
Ähnliche stackoverflow.com/questions/14046232/…
Khaled Annajar

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

aacotroneo
quelle
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>
aLIEz
quelle
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.

Roel
quelle
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.

Dandre Allison
quelle
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.

Josh Lee
quelle
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);
Isj
quelle
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);
Sohail
quelle
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.

prodev
quelle
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>
Silberschlumpf
quelle
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);
Manuel
quelle
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"
/>
Kayuri Ravrani
quelle
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"/>
Rajesh
quelle
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.

Kaiser Orionii
quelle
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.

Moritz
quelle
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.

Munaz
quelle
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"
    .../>
Yohan Dahmani
quelle
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);
Ramesh Kumar
quelle
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