Android: combinación de texto e imagen en un botón o botón de imagen

Estoy tratando de tener una imagen (como fondo) en un botón y agregar dinámicamente, dependiendo de lo que esté sucediendo durante el tiempo de ejecución, algo de texto arriba / sobre la imagen.

Si uso ImageButton Ni siquiera tengo la posibilidad de agregar texto. Si uso Button Puedo agregar texto pero solo definir una imagen con android:drawableBottom y atributos XML similares definidos aquí.

Sin embargo, estos atributos solo combinan texto e imagen en dimensiones xey, lo que significa que puedo dibujar una imagen alrededor de mi texto, pero no debajo / debajo de mi texto (con el eje z definido como saliendo de la pantalla).

¿Alguna sugerencia sobre cómo hacer esto? Una idea sería extender Button or ImageButton y anular el draw()-método. Pero con mi nivel actual de conocimiento, realmente no sé cómo hacer esto (renderizado 2D). ¿Quizás alguien con más experiencia conozca una solución o al menos algunos consejos para comenzar?

preguntado Oct 07 '09, 13:10

use 9Patch, solución inteligente -

hola @Charu ක por favor marque esto si puede stackoverflow.com/questions/42968587/… -

La mejor manera es usar CardView >> Solo pon LinearLayout dentro CardViewestablecer image como fondo de LinearLayout y use textView adentro en esto LinearLayout . Para más detalles mira esto > stackoverflow.com/a/65172123/12750160 . Gracias, Happy Coding :) -

18 Respuestas

Puedes llamar setBackground() en un Button para establecer el fondo del botón.

Cualquier texto aparecerá sobre el fondo.

Si está buscando algo similar en xml, hay: android:background atributo que funciona de la misma manera.

respondido 21 mar '18, 22:03

Si sigue esta ruta, no solo querrá usar un simple dibujable para el fondo. Use un StateListDrawable (generalmente a través de Archivo XML en res / drawable /), para que pueda definir fondos para los distintos estados (normal, presionado, enfocado, deshabilitado, etc.). - CommonsWare

De acuerdo contigo, busca esta pregunta y mi respuesta: stackoverflow.com/questions/1533038/… - m_vitaly

Que estúpido. ¿Cómo pude haber perdido eso en la documentación? Gracias por la respuesta rápida y también la pista con el . Eso es algo que definitivamente quiero implementar en el futuro. - ZNQ

No funciona bien en las versiones ICS 4.0+, la imagen se estira. Estaba usando un TextView con un fondo. - meh

Para usuarios que solo quieren poner fondo, imagen de icono y texto en uno Button de diferentes archivos: Establecer en un Button fondo, dibujable Arriba / Abajo / Derecha / Izquierda y relleno los atributos.

<Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/home_btn_test"
        android:drawableTop="@drawable/home_icon_test"
        android:textColor="#FFFFFF"
        android:id="@+id/ButtonTest"
        android:paddingTop="32sp"
        android:drawablePadding="-15sp"
        android:text="this is text"></Button>

Para un arreglo más sofisticado, también puede usar RelativeLayout (o cualquier otro diseño) y haga clic en él.

Tutorial: Gran tutorial que cubre ambos casos: http://izvornikod.com/Blog/tabid/82/EntryId/8/Creating-Android-button-with-image-and-text-using-relative-layout.aspx

Respondido el 04 de diciembre de 19 a las 09:12

Para hacer esto, use programáticamente b.setCompoundDrawablesWithIntrinsicBound(null,R.drawable.home_icon_test,null,null) en lugar de android:drawableTop y b.setPadding(0,32,0,0) en lugar de android:paddingTop. - alex jazmin

Usar un diseño como botón es en realidad un enfoque bastante flexible. - sstn

Simplemente reemplace nulo con 0 si está utilizando identificadores de recursos para sus elementos de diseño: Corrió

¿Cómo puedo escalar la imagen de fondo para que se ajuste al botón? - Alston

@Stallman Existe una solución basada en xml y en código para escalar: stackoverflow.com/questions/8223936/… - OneWorld

Hay una solución mucho mejor para este problema.

Solo toma un normal Button y utilice el drawableLeft y gravity los atributos.

<Button
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:drawableLeft="@drawable/my_btn_icon"
  android:gravity="left|center_vertical" />

De esta manera, obtiene un botón que muestra un icono en el lado izquierdo del botón y el texto en el sitio derecho del icono. vertical centrado.

Respondido el 30 de diciembre de 16 a las 12:12

Ocurre un problema con esta solución si elige tener un color de fondo en el botón (que es probable en este caso). Entonces no habrá respuesta gráfica al clic o selección. Puede escribir un selector para manejar esto, pero luego no obtendrá los colores predeterminados del teléfono. - vanja

Solo quería agregar eso Acolchado extraíble La propiedad es muy útil si se utiliza esta solución. - Nikola Malešević

¿Hay alguna forma de establecer la altura y el ancho para el icono dibujable en xml? - pengurú

Esta es una gran solución y también está respaldada oficialmente en el sitio para desarrolladores de Android: desarrollador.android.com/guide/topics/ui/controls/button.html - twaddington

si el botón es grande y el texto es largo variable, entonces se ve feo: icono en el extremo izquierdo y texto en algún lugar en el medio - user529543

enter image description here

     <Button
            android:layout_width="0dp"
            android:layout_weight="1"
            android:background="@drawable/home_button"
            android:drawableLeft="@android:drawable/ic_menu_edit"
            android:drawablePadding="6dp"
            android:gravity="left|center"
            android:height="60dp"
            android:padding="6dp"
            android:text="AndroidDhina"
            android:textColor="#000"
            android:textStyle="bold" />

Respondido el 31 de diciembre de 15 a las 15:12

Una solución simple e incorrecta. Solo para alineación a la izquierda. - CoolMind

@ CoolMind Estoy explicando solo la imagen de arriba que he adjuntado ... si desea alinear a la derecha, use drawableRight - dina k

Ni siquiera estaba pensando en hacer esto hasta que leí esta respuesta. ¡Esto funciona de maravilla! - sud007

Solo usa un LinearLayout y finge que es un Button - configuración background y se puede hacer clic es la llave:

<LinearLayout
    android:id="@+id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@android:drawable/btn_default"
    android:clickable="true"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/img"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="5dp"
        android:src="@drawable/image" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_margin="5dp"
        android:text="Do stuff" />
</LinearLayout>

Respondido el 30 de diciembre de 16 a las 12:12

¿Cómo agregar efecto de clic? - franco

La mejor respuesta, de esta manera administra el 100% de la apariencia y no tiene que pegar el ícono en un borde. - Climbatizar

franco, añadir android:onClick a tu vista - Giora Guttsait

La única solución real. Qué lío ! - gordito

solo reemplaza

android:background="@drawable/icon"

con

android:background="@android:color/transparent"
android:drawableTop="@drawable/[your background image here]"

izz un truco bastante bueno ..;)

Respondido 29 ago 12, 07:08

Adopté un enfoque diferente de los que se mencionan aquí y está funcionando muy bien, así que quería compartirlo.

Estoy usando un estilo para crear un botón personalizado con una imagen a la izquierda y texto en el centro a la derecha. Simplemente siga los 4 "sencillos pasos" a continuación:

I. Cree sus 9 parches usando al menos 3 archivos PNG diferentes y la herramienta que tiene en: /YOUR_OWN_PATH/android-sdk-mac_x86/tools/./draw9patch. Después de esto, debería tener:

button_normal.9.png, button_focused.9.png y button_pressed.9.png

Luego descargue o cree un icono PNG de 24x24.

ic_tu_icono.png

Guarde todo en la carpeta dibujable / en su proyecto de Android.

II. Cree un archivo XML llamado button_selector.xml en su proyecto en la carpeta drawable /. Los estados deberían ser así:

<item android:state_pressed="true" android:drawable="@drawable/button_pressed" />
<item android:state_focused="true" android:drawable="@drawable/button_focused" />
<item android:drawable="@drawable/button_normal" />

III. Vaya a la carpeta valores / y abra o cree el archivo styles.xml y cree el siguiente código XML:

<style name="ButtonNormalText" parent="@android:style/Widget.Button">
    <item name="android:textColor" >@color/black</item>
    <item name="android:textSize" >12dip</item>
    <item name="android:textStyle" >bold</item>
    <item name="android:height" >44dip</item>
    <item name="android:background" >@drawable/button_selector</item>
    <item name="android:focusable" >true</item>
    <item name="android:clickable" >true</item>
</style>

<style name="ButtonNormalTextWithIcon" parent="ButtonNormalText">
    <item name="android:drawableLeft" >@drawable/ic_your_icon</item>
</style>

ButtonNormalTextWithIcon es un "estilo secundario" porque extiende ButtonNormalText (el "estilo principal").

Tenga en cuenta que cambiando el drawableLeft en el estilo ButtonNormalTextWithIcon, a drawableRight, drawableTop o drawableBottom puede colocar el icono en otra posición con respecto al texto.

IV. Vaya al diseño / carpeta donde tiene su XML para la interfaz de usuario y vaya al Botón donde desea aplicar el estilo y haga que se vea así:

<Button android:id="@+id/buttonSubmit" 
android:text="@string/button_submit" 
android:layout_width="fill_parent" 
android:layout_height="wrap_content" 
style="@style/ButtonNormalTextWithIcon" ></Button>

¡Y voilá! Tienes tu botón con una imagen en el lado izquierdo.

Para mí, ¡esta es la mejor manera de hacerlo! porque al hacerlo de esta manera, puede administrar el tamaño del texto del botón por separado del ícono que desea mostrar y usar el mismo fondo dibujable para varios botones con diferentes íconos respetando las Pautas de la IU de Android usando estilos.

También puede crear un tema para su aplicación y agregarle el "estilo principal" para que todos los botones tengan el mismo aspecto, y aplicar el "estilo secundario" con el icono solo donde lo necesite.

Respondido 04 ago 15, 19:08

Buen trabajo. Estaba usando un enfoque de vista FrameLayout con ImageView y TextView adentro, pero este enfoque es mejor. - pipa de agua

Enfoque impresionante. El SDK de Facebook (versión 3) adopta el mismo enfoque para el botón de inicio de sesión: Alguien en alguna parte

 <Button android:id="@+id/imeageTextBtn" 
        android:layout_width="240dip"
        android:layout_height="wrap_content"
        android:text="Side Icon With Text Button"
        android:textSize="20sp"
        android:drawableLeft="@drawable/left_side_icon"         
        />   

Respondido 20 Oct 11, 09:10

Actualización importante

No use normal android:drawableLeft etc ... con elementos de diseño vectoriales, de lo contrario caída in versiones de API inferiores. (Lo he enfrentado en la aplicación en vivo)

Para vector dibujable

Si está utilizando un elemento de diseño vectorial, debe

  • ¿Ha migrado a AndroidX? si no, primero debe migrar a AndroidX. Es muy simple, mira ¿Qué es androidx y cómo migrar?
  • Fue lanzado en versión 1.1.0-alpha01, por lo que la versión de appcompat debe ser al menos 1.1.0-alpha01. La última versión actual es 1.1.0-alpha02, use las últimas versiones para una mayor confiabilidad, consulte las notas de la versión - aquí.

    implementation 'androidx.appcompat:appcompat:1.1.0-alpha02'

  • Utiliza AppCompatTextView/AppCompatButton/AppCompatEditText

  • Utiliza app:drawableLeftCompat, app:drawableTopCompat, app:drawableRightCompat, app:drawableBottomCompat, app:drawableStartCompat y app:drawableEndCompat

Para dibujar regular

Si no necesita un dibujo vectorial, puede

  • utilizado android:drawableLeft, android:drawableRight, android:drawableBottom, android:drawableTop
  • Puede usar regular TextView, Button & EditText or AppCompat clases.

Puedes lograr Salida como abajo -

salida

respondido 09 mar '19, 03:03

Estoy usando xmlns:app="http://schemas.android.com/apk/res-auto" espacio de nombres y no veo esas cosas de compatibilidad de aplicaciones. - Dale

@Dale, su espacio de nombres es correcto, he actualizado mi respuesta, consulte For vector drawable apuntar de nuevo. - khemraj

@Khemraj ¿Cómo está centrando tanto el dibujo como el texto en la vista única (ya sea TextView o Button u otra cosa) como se muestra en la imagen que adjuntó? - ámbar jainista

Puede usar el drawableTop (También drawableLeft, etc.) para la imagen y establezca el texto debajo de la imagen agregando el gravity left|center_vertical

<Button
            android:id="@+id/btn_video"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:background="@null"
            android:drawableTop="@drawable/videos"
            android:gravity="left|center_vertical"
            android:onClick="onClickFragment"
            android:text="Videos"
            android:textColor="@color/white" />

Respondido el 30 de diciembre de 16 a las 12:12

Probablemente mi solución sea adecuada para muchos usuarios, eso espero.

Lo que estoy sugiriendo es hacer TextView con su estilo. Me funciona perfectamente y tiene todas las funciones, como un botón.

En primer lugar, hagamos un estilo de botón, que puede usar en todas partes ... Estoy creando button_with_hover.xml

    <?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" >
        <shape android:shape="rectangle"  >
            <corners android:radius="3dip" />
            <stroke android:width="1dip" android:color="#8dbab3" />
            <gradient android:angle="-90" android:startColor="#48608F" android:endColor="#48608F"  />
        </shape>

        <!--#284682;-->
        <!--border-color: #223b6f;-->
    </item>
    <item android:state_focused="true">
        <shape android:shape="rectangle"  >
            <corners android:radius="3dip" />
            <stroke android:width="1dip" android:color="#284682" />
            <solid android:color="#284682"/>
        </shape>
    </item>
    <item >
        <shape android:shape="rectangle"  >
            <corners android:radius="3dip" />
            <stroke android:width="1dip" android:color="@color/ControlColors" />
            <gradient android:angle="-90" android:startColor="@color/ControlColors" android:endColor="@color/ControlColors" />
        </shape>
    </item>

</selector>

En segundo lugar, creemos un botón de vista de texto.

    <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginBottom="20dip"
    android:layout_gravity="right|bottom"
    android:gravity="center"
    android:padding="12dip"
    android:background="@drawable/button_with_hover"
    android:clickable="true"
    android:drawableLeft="@android:drawable/btn_star_big_off"
    android:textColor="#ffffffff"
    android:text="Golden Gate" />

Y este es un resultado. Luego, diseñe su botón personalizado con cualquier color o cualquier otra propiedad y margen. Buena suerte

enter image description here

Respondido 22 Feb 17, 13:02

Aunque todavía tengo que probar su código, ya que el enfoque parece ser correcto, pero no entiendo la razón del efecto de desplazamiento en una aplicación móvil. - Mohamed Akhtar Zuberi

He creado un efecto de desplazamiento para mi aplicación, y durante la compilación de la aplicación necesitaba el efecto de desplazamiento. Pero depende de usted :) Puede eliminar el efecto de desplazamiento si no es necesario. - Jevgenij Kononov

He votado a favor de su respuesta porque es un enfoque muy bueno. Mi único punto es una interfaz móvil, ¿cómo puedes desplazarte? - Mohamed Akhtar Zuberi

Oo ... ya veo ...: D Sí, tienes razón. Es imposible. Ese efecto de desplazamiento es principalmente para presionar el efecto. Solo nombre incorrecto para la clase xml - Jevgenij Kononov

<Button
     android:id="@+id/groups_button_bg"
     android:layout_height="wrap_content"
     android:layout_width="wrap_content"
     android:text="Groups"
     android:drawableTop="@drawable/[image]" />


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

http://www.mokasocial.com/2010/04/create-a-button-with-an-image-and-text-android/

respondido 14 mar '13, 13:03

Este código me funciona perfectamente

<LinearLayout
    android:id="@+id/choosePhotosView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:gravity="center"
    android:clickable="true"
    android:background="@drawable/transparent_button_bg_rev_selector">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/choose_photo"/>

     <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@android:color/white"
        android:text="@string/choose_photos_tv"/>

</LinearLayout>

Respondido 24 Jul 15, 11:07

He probado tu código ... funciona, pero el problema principal de tu código es si tienes un conjunto de botones, con diferentes tamaños de texto en cada botón. Se cambiará su diseño. Entonces, cada posición de imagen del botón estará en un lugar diferente. Mientras que debe quedar recto en el centro. Esto es lo que sucede con el botón. - Jevgenij Kononov

MaterialBotón tiene soporte para configurar un icono y alinearlo con el texto:

<com.google.android.material.button.MaterialButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="My button"
        app:icon="@drawable/your_icon"
        app:iconGravity="textStart"
        />

app:iconGravity también puede ser para start / end si desea alinear el icono con el botón en lugar del texto dentro de él.

Respondido 03 Jul 20, 12:07

<Button android:id="@+id/myButton" 
    android:layout_width="150dp"
    android:layout_height="wrap_content"
    android:text="Image Button"
    android:drawableTop="@drawable/myimage"         
    />  

O puedes programáticamente:

Drawable drawable = getResources.getDrawable(R.drawable.myimage);
drawable.setBounds(0, 0, 60, 60);
myButton.setCompoundDrawables(null, drawable, null, null);//to the Top of the Button

contestado el 14 de mayo de 20 a las 14:05

Puedes usar esto:

  <Button
                    android:id="@+id/reset_all"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginRight="5dp"
                    android:layout_weight="1"
                    android:background="@drawable/btn_med"
                    android:text="Reset all"
                    android:textColor="#ffffff" />

                <Button
                    android:id="@+id/undo"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="5dp"
                    android:layout_weight="1"
                    android:background="@drawable/btn_med"
                    android:text="Undo"
                    android:textColor="#ffffff" />

en eso he puesto una imagen como background y también agregó texto ..!

Respondido el 30 de diciembre de 16 a las 12:12

Haz un botón falso.

Es realmente la unica manera

  <FrameLayout
        android:id="@+id/fake_button"

        android:layout_width=" .. "
        android:layout_height=" .. "

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

        android:clickable="true"
        android:onClick="tappedNext">

        <ImageView
            android:id="@+id/fake_image"
            android:layout_width="match_parent"
            android:layout_height="match_parent"

            android:src="@drawable/your_amazing_drawable" />

        <TextView
            android:id="@+id/fake_text"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"

            android:text="Next"
            android:fontFamily="@font/ .. "
            android:textColor="@color/ .. "
            android:textSize=" .. " />
    </FrameLayout>

respondido 03 mar '21, 22:03

    <ImageView
        android:id="@+id/iv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        android:src="@drawable/temp"
        />

Respondido el 01 de enero de 18 a las 08:01

Esta no es una respuesta correcta porque la vista de imagen no admite texto: Muhammed Fasil

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.