Como criar botões padrão sem borda (como na diretriz de design mencionada)?


113

Eu estava apenas verificando as diretrizes de design e me perguntando sobre os botões sem borda. Eu arregalei os olhos e tentei encontrar a fonte, mas não consigo reuni-la sozinho. Este é o widget de botão normal, mas você adiciona um estilo personalizado (padrão do Android)? Como fazer esses botões sem borda (claro que você pode definir o fundo como vazio, mas eu não tenho o divisor)?

Aqui estão os links para as diretrizes de design:

insira a descrição da imagem aqui


Respostas:


163

Para limpar alguma confusão:

Isso é feito em 2 etapas: Definir o atributo de fundo do botão como android: attr / selectableItemBackground cria um botão com feedback, mas sem fundo.

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

A linha para dividir o botão sem borda do restante do layout é feita por uma visualização com o Android de fundo : attr / dividerVertical

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

Para uma melhor compreensão, aqui está um layout para uma combinação de botões OK / Cancelar sem borda na parte inferior da tela (como na imagem à direita acima).

<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
Vale ressaltar: esta solução só funciona para API nível 11+.

9
Se você usar o HoloEverywhere, ele funcionará para o nível 7 da API. Você deve mudar ?android:attr/selectableItemBackgroundpara ?attr/selectableItemBackgrounde ?android:attr/dividerVerticalpara?attr/dividerVertical
Brais Gabin

1
?android:attr/dividerVerticalfore ?attr/dividerVerticaltambém funciona para abs
oscarthecat


22

Resposta tardia, mas muitos pontos de vista. Como as APIs <11 ainda não morreram, para os interessados ​​aqui está um truque.

Deixe seu container ter a cor desejada (pode ser transparente). Em seguida, dê aos seus botões um seletor com a cor transparente padrão e alguma cor quando pressionados. Dessa forma, você terá um botão transparente, mas mudará de cor quando pressionado (como o holo). Você também pode adicionar alguma animação (como holo). O seletor deve ser algo assim:

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 o botão deveria ter android:background="@drawable/selector_transparent_button"

PS: deixe seu container ter as divisórias ( android:divider='@android:drawable/...para API <11)

PS [Iniciantes]: você deve definir essas cores em values ​​/ colors.xml


Isso funcionou perfeitamente para API Level 10e API Level > 10!
theblang

Isso é melhor do que fazê-lo programaticamente, embora ambos funcionassem.
Eran Goldin

1
O atributo "exitFadeDuration" é usado apenas na API de nível 11 e superior.
Bevor

sim @Bevor, boa. Os leitores consideram que as tags xml desconhecidas são ignoradas, portanto, usará o esmaecimento para api> = 11 e funcionará apenas para <11
aacotroneo

18

Para quem deseja botões sem borda, mas ainda animados quando clicados. Adicione isso no botão.

style="?android:attr/borderlessButtonStyle"

Se você quiser uma divisória / linha entre eles. Adicione isso no layout linear.

style="?android:buttonBarStyle"

Resumo

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

mais para buttonBarStyle. e esta é a resposta btw.
Frostymarvelous

7

Para estilo de material, adicione style="@style/Widget.AppCompat.Button.Borderless"ao usar a biblioteca AppCompat.


5

Da fonte do aplicativo iosched, criei esta ButtonBarclasse:

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

Este será o local em LinearLayoutque os botões "OK" e "Cancelar" serão colocados e tratará de colocá-los na ordem apropriada. Em seguida, coloque isso no layout em que deseja que os botões:

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

Isso dá a você a aparência de um diálogo com botões sem bordas. Você pode encontrar esses atributos no res na estrutura. buttonBarStylefaz a divisória vertical e o preenchimento. buttonBarButtonStyleestá definido como borderlessButtonStylepara o tema Holo, mas acredito que esta seja a maneira mais robusta de exibi-lo como o framework deseja exibi-lo.


como eu poderia colocar isso (? android: attr / buttonBarButtonStyle) em styles.xml como item de um estilo?
lis

4

Olhar para o tema atributos buttonBarStyle, buttonBarButtonStylee borderlessButtonStyle.


Se eu usar buttonBarButtonStyle, recebo uma exceção 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}Não tenho ideia do porquê, mas usando faz selectableItemBackgroundmaravilhas.
Alguém em algum lugar de

4

Você também pode tornar os botões sem bordas por meio do código:

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

Está funcionando, obrigado. Mas android.R.attr.selectableItemBackgroundrequer API 21. Alguma ideia de como fazer isso em versões anteriores?
arenaq

Não está funcionando. Estou tentando definir o recurso de android.R.attr.buttonBarButtonStyle e diz que o recurso não foi encontrado.
Kristy Welsh

use android.R.attr.selectableItemBackground
Isj

2

Para aqueles que desejam criar botão sem borda programaticamente para APIs> = 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);

Isso é melhor e mais simples do que a solução de lsj. Apenas setBackgroundResource (0)
jk7

2

Outra solução que deve funcionar nas plataformas Android mais antigas e mais recentes é usar

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

atributo para a visualização do botão. Mas depois de adicionar o botão da linha acima não fornecerá feedback de toque.

Para fornecer feedback de toque, adicione o seguinte código à 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;
    }
});

Está funcionando bem para mim.


Eu adicionaria case MotionEvent.ACTION_CANCEL: abaixo do case MotionEvent.ACTION_UP: também.
Medo

2

Para quem ainda está procurando:

herde seu próprio estilo para as barras de botão Holo:

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

ou Holo Light:

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

e para botões Holo sem borda:

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

ou Holo Light:

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

2

É assim que você cria um botão sem borda (plano) programaticamente sem usar 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);

Eu estava usando: ContextThemeWrapper myContext = new ContextThemeWrapper(this.getActivity(), R.style.Widget_AppCompat_Button_Borderless_Colored); Button myButton = new Button(myContext); e não funcionava. Depois de adicionar o 2º e o 3º parâmetro, está funcionando!
levibostian

1

Use o código abaixo em seu arquivo xml. Use android: background = "# 00000000" para obter a cor transparente.

<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

Você pode usar a Biblioteca de Suporte AppCompat para botão sem borda.

Você pode fazer um botão sem borda como este:

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

Você pode fazer um botão colorido sem borda como este:

<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

Por algum motivo, nem style="Widget.Holo.Button.Borderless"nem android:background="?android:attr/selectableItemBackground"funcionou para mim. Para ser mais preciso, Widget.Holo.Button.Borderlessfuncionou no Android 4.0, mas não funcionou no Android 2.3.3. O que funcionou para mim em ambas as versões foi android:background="@drawable/transparent"este XML em res / drawable / transparent.xml:

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

Cabeça plana através da abordagem da parede.


2
Definir o fundo como @android: color / transparent funcionou para mim, sem a necessidade do arquivo XML extra.
Nicolai Buch-Andersen

Isso não inclui como obter o divisor.
Navarr de

3
@Navarr de acordo com a resposta de Blundell, divisor não faz parte do "botão sem borda". Nem deveria ser porque os botões e qualquer outra classe de visualização não devem ser informados sobre os componentes GUI em torno. Isso é responsabilidade do contêiner. Nos comentários da postagem de Blundell, há um link para o que parece ser o layout do item de detalhes do contato do ICS. Há uma visão extra (com id vertical_divider) para exibir o divisor. Nenhuma solução fora da caixa para divisórias automáticas, embora haja um android:background="?android:attr/dividerVertical"truque interessante.
Imperador Orionii

A questão dos OPs referia-se aos "Botões sem borda" do Android UX, e em todos os exemplos eles têm o divisor - que aparentemente faz parte do buttonBarStyle. Embora você tenha me dado algumas informações muito úteis, obrigado.
Navarr

0

Uma ótima apresentação de slides sobre como conseguir o efeito desejado do Google Nick Butcher (comece no slide 20). Ele usa o Android padrão @attrpara estilizar o botão e o divisor.


Observe que as respostas somente com link são desencorajadas, as respostas do SO devem ser o ponto final de uma busca por uma solução (em vez de outra parada de referências, que tendem a ficar obsoletas com o tempo). Considere adicionar uma sinopse independente aqui, mantendo o link como uma referência.
kleopatra

0

Adicionando à resposta principal, você também pode usar visualizações com uma cor de fundo cinza escuro em um Layout Linear como este.

<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 a sua linha for horizontal, você deve definir a altura para 1 mergulho e a largura para corresponder ao pai e vice-versa se a linha for vertical.


0

Se você deseja obter o mesmo programaticamente:

(isso é C #, mas facilmente transacionável para Java)

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

Combine

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

0

Tente este código, para remover o drawable de fundo (@ drawable / bg) programaticamente, apenas precisamos fornecer null como parâmetro.

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

1
Obrigado por este trecho de código, que pode fornecer alguma ajuda limitada e imediata. Uma explicação adequada melhoraria muito seu valor a longo prazo, mostrando por que essa é uma boa solução para o problema e a tornaria mais útil para futuros leitores com outras questões semelhantes. Por favor edite sua resposta para adicionar alguma explicação, incluindo as suposições que você fez.
NOhs
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.