Come creare pulsanti senza bordi standard (come nelle linee guida di progettazione menzionate)?


113

Stavo solo controllando le linee guida di progettazione e chiedendomi quali fossero i pulsanti senza bordi. Ho guardato a bocca aperta e ho cercato di trovare nella fonte ma non riesco a metterlo insieme da solo. È il normale widget Button ma aggiungi uno stile personalizzato (predefinito di Android)? Come creare questi pulsanti senza bordi (ovviamente puoi impostare lo sfondo su vuoto, ma poi non ho il divisore)?

Qui i collegamenti alle linee guida di progettazione:

inserisci qui la descrizione dell'immagine


Risposte:


163

Per eliminare un po 'di confusione:

Ciò avviene in 2 passaggi: L'impostazione dell'attributo di sfondo del pulsante su android: attr / selectableItemBackground crea un pulsante con feedback ma senza sfondo.

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

La linea per dividere il pulsante senza bordi dal resto del layout viene eseguita da una vista con lo sfondo android: attr / dividerVertical

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

Per una migliore comprensione, ecco un layout per una combinazione di pulsanti senza bordi OK / Annulla nella parte inferiore dello schermo (come nell'immagine sopra a destra).

<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
Da sottolineare: questa soluzione funziona solo per il livello API 11+.

9
Se usi HoloEverywhere , funziona per il livello API 7+. Devi cambiare ?android:attr/selectableItemBackgroundper ?attr/selectableItemBackgrounde ?android:attr/dividerVerticalper?attr/dividerVertical
Brais Gabin

1
?android:attr/dividerVerticalfore ?attr/dividerVerticalfunziona anche per gli addominali
oscarthecat


22

Risposta in ritardo, ma molti punti di vista. Poiché le API <11 non sono ancora morte, per chi è interessato qui è un trucco.

Lascia che il tuo contenitore abbia il colore desiderato (potrebbe essere trasparente). Quindi dai ai tuoi pulsanti un selettore con colore trasparente predefinito e un po 'di colore quando viene premuto. In questo modo avrai un pulsante trasparente, ma cambierà colore quando viene premuto (come l'olo). Puoi anche aggiungere qualche animazione (come quella di holo). Il selettore dovrebbe essere qualcosa del genere:

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>

E il pulsante dovrebbe avere android:background="@drawable/selector_transparent_button"

PS: lascia che il contenitore abbia i divisori ( android:divider='@android:drawable/...per API <11)

PS [Newbies]: dovresti definire quei colori in values ​​/ colors.xml


Questo ha funzionato perfettamente per entrambi API Level 10e API Level > 10!
theblang

È meglio che farlo a livello di programmazione anche se entrambi funzionerebbero.
Eran Goldin

1
L'attributo "exitFadeDuration" viene utilizzato solo nel livello API 11 e superiore.
Bevor

sì @Bevor, simpatico. I lettori considerano che i tag xml sconosciuti vengono ignorati, quindi utilizzerà la dissolvenza per api> = 11 e funzionerà solo per <11
aacotroneo

18

Per chi desidera pulsanti senza bordi ma comunque animati quando cliccati. Aggiungi questo nel pulsante.

style="?android:attr/borderlessButtonStyle"

Se volessi un divisore / linea tra di loro. Aggiungilo nel layout lineare.

style="?android:buttonBarStyle"

Sommario

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

più per buttonBarStyle. e questa è la risposta btw.
frostymarvelous

7

Per lo stile del materiale aggiungere style="@style/Widget.AppCompat.Button.Borderless"quando si utilizza la libreria AppCompat.


5

Dalla fonte dell'app iOS ho creato questa ButtonBarlezione:

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

Questo sarà il posto in LinearLayoutcui entreranno i pulsanti "OK" e "Annulla" e gestiranno inserendoli nell'ordine appropriato. Quindi inseriscilo nel layout in cui desideri inserire i pulsanti:

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

Questo ti dà l'aspetto della finestra di dialogo con pulsanti senza bordi. Puoi trovare questi attributi nella res nel framework. buttonBarStylefa il divisore verticale e l'imbottitura. buttonBarButtonStyleè impostato come borderlessButtonStyleper il tema Holo, ma credo che questo dovrebbe essere il modo più robusto per visualizzarlo come il framework vuole visualizzarlo.


come potrei mettere questo (? android: attr / buttonBarButtonStyle) in styles.xml come elemento di uno stile?
lis

4

Guardate nel tema attributi buttonBarStyle, buttonBarButtonStylee borderlessButtonStyle.


Se uso buttonBarButtonStyleottengo un'eccezione 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}Non ho idea del perché, ma l'uso selectableItemBackgroundfunziona a meraviglia.
Someone Somewhere

4

Puoi rendere i pulsanti senza bordi anche attraverso il codice:

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

Funziona, grazie. Ma android.R.attr.selectableItemBackgroundrichiede l'API 21. Qualche idea su come farlo nelle versioni precedenti?
arenaq

La sua non funziona. Sto cercando di impostare la risorsa di android.R.attr.buttonBarButtonStyle e si dice che la risorsa non può essere trovata.
Kristy Welsh

usa android.R.attr.selectableItemBackground
Isj

2

Per coloro che desiderano creare un pulsante senza bordi a livello di codice per 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);

Questa è migliore, più semplice della soluzione di lsj. Basta impostareBackgroundResource (0)
jk7

2

Un'altra soluzione che dovrebbe funzionare sia sulla piattaforma Android più vecchia che su quella più recente è quella di utilizzare

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

attributo per la visualizzazione dei pulsanti. Ma dopo aver aggiunto il pulsante sopra la riga non fornirà feedback tattile.

Per fornire feedback tattile, aggiungi il codice seguente alla classe 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;
    }
});

Funziona bene per me.


Aggiungerei anche di case MotionEvent.ACTION_CANCEL: seguito case MotionEvent.ACTION_UP: .
Medo

2

Per chiunque stia ancora cercando:

eredita il tuo stile per le barre dei pulsanti Holo:

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

o Holo Light:

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

e per i pulsanti Holo senza bordi:

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

o Holo Light:

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

2

Ecco come creare un pulsante senza bordi (piatto) a livello di codice senza utilizzare 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);

Stavo usando: ContextThemeWrapper myContext = new ContextThemeWrapper(this.getActivity(), R.style.Widget_AppCompat_Button_Borderless_Colored); Button myButton = new Button(myContext); e non avrebbe funzionato. Dopo aver aggiunto il 2 ° e 3 ° parametro, funziona!
levibostian

1

Usa il codice seguente nel tuo file xml. Usa android: background = "# 00000000" per avere il colore trasparente.

<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

È possibile utilizzare la libreria di supporto AppCompat per il pulsante senza bordi.

Puoi creare un pulsante senza bordi come questo:

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

Puoi creare un pulsante colorato senza bordi in questo modo:

<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

Per qualche motivo né style="Widget.Holo.Button.Borderless"né ha android:background="?android:attr/selectableItemBackground"funzionato per me. Per essere più precisi Widget.Holo.Button.Borderlessha funzionato su Android 4.0 ma non su Android 2.3.3. Qual è stato il trucco per me su entrambe le versioni android:background="@drawable/transparent"e questo XML in res / drawable / transparent.xml:

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

Testa normale attraverso l'approccio al muro.


2
L'impostazione dello sfondo su @android: color / transparent ha funzionato per me, senza la necessità del file XML aggiuntivo.
Nicolai Buch-Andersen

Questo non include come ottenere il divisore.
Navarr

3
@Navarr secondo la risposta di Blundell, il divisore non fa parte del "pulsante senza bordi". Né dovrebbe essere perché i pulsanti e qualsiasi altra classe di visualizzazione non dovrebbero essere informati sui componenti della GUI circostanti. Questa è la responsabilità del container. Nei commenti al post di Blundell c'è un collegamento a quello che sembra essere il layout degli elementi dei dettagli dei contatti ICS. C'è una vista extra (con vertical_divider id) per la visualizzazione del divisore. Nessuna soluzione pronta all'uso per divisori automatici, anche se c'è un android:background="?android:attr/dividerVertical"trucco accurato .
Imperatore Orionii,

La domanda degli OP si riferiva ai "Borderless Buttons" di Android UX, e in tutti gli esempi hanno il divisore, che apparentemente fa parte di buttonBarStyle. Anche se mi hai fornito alcune informazioni molto utili, grazie.
Navarr

0

Una fantastica presentazione su come ottenere l'effetto desiderato da Nick Butcher di Google (inizia dalla diapositiva 20). Usa l'androide standard @attrper modellare il pulsante e il divisore.


Nota che le risposte di solo collegamento sono scoraggiate, quindi le risposte dovrebbero essere il punto finale di una ricerca di una soluzione (rispetto a un'altra sosta di riferimenti, che tendono a diventare obsoleti nel tempo). Si prega di considerare l'aggiunta di una sinossi indipendente qui, mantenendo il collegamento come riferimento.
kleopatra

0

Aggiungendo alla risposta in alto puoi anche usare le viste con uno sfondo grigio scuro in un layout lineare in questo modo.

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

Se la tua linea è orizzontale ti consigliamo di impostare l'altezza a 1dip e la larghezza per abbinare il genitore e viceversa se la tua linea è verticale.


0

Se vuoi ottenere lo stesso risultato a livello di programmazione:

(questo è C # ma facilmente trasferibile a Java)

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

Incontro

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

0

Prova questo codice, per rimuovere lo sfondo drawable (@ drawable / bg) a livello di programmazione, è sufficiente fornire null come parametro.

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

1
Grazie per questo snippet di codice, che potrebbe fornire un aiuto limitato e immediato. Una spiegazione adeguata migliorerebbe notevolmente il suo valore a lungo termine mostrando perché questa è una buona soluzione al problema e la renderebbe più utile ai futuri lettori con altre domande simili. Si prega di modificare la risposta di aggiungere qualche spiegazione, tra le ipotesi che hai fatto.
NOhs
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.