Botão Android com ícone e texto

97

Tenho alguns botões como este em meu aplicativo:

    <Button
        android:id="@+id/bSearch"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:padding="16dp"
        android:text="Search"
        android:textSize="24sp" />

Estou tentando criar um mesmo botão com texto e um ícone. android: drawableLeft não funciona para mim (talvez funcionasse, mas não sei como definir uma altura máxima para o ícone).

Então, criei um LinearLayout com um ImageView e um TextView e o fiz funcionar como um botão:

    <LinearLayout
        android:id="@+id/bSearch2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@android:drawable/btn_default"
        android:clickable="true"
        android:padding="16dp"
        android:orientation="horizontal" >

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_marginLeft="5dp"
            android:adjustViewBounds="true"
            android:maxHeight="30dp"
            android:maxWidth="30dp"
            android:scaleType="fitCenter"
            android:src="@drawable/search_icon" />

        <TextView
            android:id="@+id/tvSearchCaption"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:textSize="24sp"
            android:paddingRight="30dp"
            android:gravity="center"
            android:text="Search" />
    </LinearLayout>

Meu novo botão é exatamente o que eu quero (tamanho da fonte, ícone e posicionamento do texto). Mas não se parece com meus botões padrão:

insira a descrição da imagem aqui

Então tentei mudar o fundo e a cor do texto do meu novo botão:

Button Search = (Button) findViewById(R.id.bSearch);
LinearLayout bSearch2 = (LinearLayout) findViewById(R.id.bSearch2);
bSearch2.setBackground(bSearch.getBackground());
TextView tvSearchCaption = (TextView)findViewById(R.id.tvSearchCaption);
tvSearchCaption.setTextColor(bSearch.getTextColors().getDefaultColor());

Isso dá um resultado estranho, meu botão antigo fica bagunçado:

insira a descrição da imagem aqui

Quando eu mudo a ordem desses dois botões no XML, para que o "novo botão" vá primeiro, ele produz outro resultado estranho:

insira a descrição da imagem aqui

Agora eu percebi que, quando tento pressionar o botão antigo, o novo é pressionado.

Alguma ideia?

Dusan
fonte

Respostas:

288

Tente este.

<Button
    android:id="@+id/bSearch"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:padding="16dp"
    android:text="Search"
    android:drawableLeft="@android:drawable/ic_menu_search"
    android:textSize="24sp"/>
Liem Vo
fonte
3
Parece exatamente como eu quero, mas quero usar meus próprios ícones, não os ícones padrão do Android. Meus ícones são maiores. Isso significa que preciso criar bitmaps menores para cada resolução? Existe algum parâmetro que me permite controlar o tamanho do ícone?
Dusan,
Está correto. Você precisa criar tamanhos de imagem diferentes para cada resolução
Liem Vo,
Ok, obrigado pela ajuda, mas agora tenho outra pergunta ... Meus ícones são claros, porque o texto é branco em um botão escuro, como vocês podem ver nas imagens da minha pergunta. O aplicativo está configurado para usar um tema que está disponível na versão Android. Meus exemplos são do Android 4.3. Quando o aplicativo é executado no Android 2.3.3, os botões padrão são claros com texto escuro. Algo como o botão da minha primeira imagem. Existe uma maneira de fornecer um bitmap alternativo para o ícone em execução em dispositivos mais antigos. Espero que você entenda minha pergunta :)
Dusan
Essa é uma boa pergunta. Você pode definir um estilo diferente para o seu ícone, estilo de texto mais frio para cada nível de API (significa versão do sistema operacional Android). Você pode ver as pastas values-v11, values-v14.
Liem Vo
3
Você também pode adicionar preenchimento ao ícone android: drawablePadding = ""
Asad Mirza
15

Para adicionar uma imagem à esquerda, direita, superior ou inferior, você pode usar atributos como este:

android:drawableLeft
android:drawableRight
android:drawableTop
android:drawableBottom

O código de amostra é fornecido acima. Você também pode conseguir isso usando o layout relativo.

user3515854
fonte
1
Como faço isso programaticamente
Sujay UN
1
Você poderia dizer em android:drawableStartvez de Esquerda e em android:drawableEndvez de Direita.
Simão Garcia
@ SimãoGarcia * deveria. O início deve substituir a direita e a extremidade deve substituir a esquerda em todos os lugares. Isso é para garantir que a leitura da direita para a esquerda, bem como da esquerda para a direita, esteja disponível, já que alguns outros países têm uma leitura diferente.
Carson J.
11

Para quem deseja fazer isso dinamicamente, setCompoundDrawables(Drawable left, Drawable top, Drawable right, Drawable bottom)o objeto de botões ajudará.

Amostra

Button search = (Button) findViewById(R.id.yoursearchbutton);
search.setCompoundDrawables('your_drawable',null,null,null);
Kennedy Nyaga
fonte
5
O uso de setCompoundDrawables não refletiu na IU. Em vez disso, usei setCompoundDrawablesWithIntrinsicBounds e funcionou.
Aldo
7

Você pode usar a Biblioteca de Componentes de Materiais e o MaterialButtoncomponente.
Use os atributos app:icone app:iconGravity="start".

Algo como:

  <com.google.android.material.button.MaterialButton
        style="@style/Widget.MaterialComponents.Button.Icon"
        app:icon="@drawable/..."
        app:iconGravity="start"
        ../>

insira a descrição da imagem aqui

Gabriele Mariotti
fonte
Observe que, se você tiver um tema de design de material para seu aplicativo, o widget Button padrão é automaticamente inflado como MaterialButton. Por aqui - material.io/develop/android/components/buttons
dodgy_coder
6

Isso é o que você realmente quer.

<Button
       android:id="@+id/settings"
       android:layout_width="190dp"
       android:layout_height="wrap_content"
       android:layout_gravity="center_horizontal"
       android:background="@color/colorAccent"
       android:drawableStart="@drawable/ic_settings_black_24dp"
       android:paddingStart="40dp"
       android:paddingEnd="40dp"
       android:text="settings"
       android:textColor="#FFF" />
Stackoverflower
fonte
2

A resposta de @Liem Vo está correta se você estiver usando android.widget.Button sem qualquer substituição. Se você estiver substituindo seu tema usando MaterialComponents, isso não resolverá o problema.

Então se você é

  1. Usando com.google.android.material.button.MaterialButton ou
  2. Substituindo AppTheme usando MaterialComponents

Use app: parâmetro de ícone .

<Button
    android:id="@+id/bSearch"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:padding="16dp"
    android:text="Search"
    android:textSize="24sp"
    app:icon="@android:drawable/ic_menu_search" />
Chamin Wickramarathna
fonte