Android: combinazione di testo e immagine su un pulsante o ImageButton


540

Sto cercando di avere un'immagine (come sfondo) su un pulsante e aggiungerla in modo dinamico, a seconda di ciò che accade durante il runtime, del testo sopra / sopra l'immagine.

Se uso ImageButtonnon ho nemmeno la possibilità di aggiungere testo. Se uso Buttonposso aggiungere del testo ma definire solo un'immagine con android:drawableBottome attributi XML simili come definito qui .

Tuttavia, questi attributi combinano solo testo e immagine nelle dimensioni X e Y, il che significa che posso disegnare un'immagine attorno al mio testo, ma non sotto / sotto il mio testo (con l'asse z definito come uscente dal display).

Qualche suggerimento su come fare questo? Un'idea sarebbe quella di estendere Buttono ImageButtonignorare il draw()metodo. Ma con il mio attuale livello di conoscenza non so davvero come farlo (rendering 2D). Forse qualcuno con più esperienza conosce una soluzione o almeno alcuni suggerimenti per iniziare?


usa 9Patch, soluzione intelligente
Kaveh Garshasp,

hi @Charu ක si prega di controllare questo se si può stackoverflow.com/questions/42968587/...
Mohamed Rihan

Risposte:


205

È possibile chiamare setBackground()a Buttonper impostare lo sfondo del pulsante.

Qualsiasi testo verrà visualizzato sopra lo sfondo.

Se stai cercando qualcosa di simile in xml c'è: android:backgroundattributo che funziona allo stesso modo.


49
Se segui questa strada, non vuoi semplicemente usare un semplice disegno per lo sfondo. Utilizzare un StateListDrawable (di solito tramite il file XML <selector> in res / drawable /), in modo da poter definire gli sfondi per i vari stati (normale, premuto, focalizzato, disabilitato, ecc.).
CommonsWare

D'accordo con te, look per questa domanda e la mia risposta: stackoverflow.com/questions/1533038/...
m_vitaly

1
Che stupido. Come potrei averlo perso nella documentazione. Grazie per la risposta rapida e anche per il suggerimento con <selector>. È qualcosa che sicuramente voglio implementare in futuro.
znq,

3
Non funziona bene sulle versioni ICS 4.0+, l'immagine si allunga. Stavo usando un TextView con uno sfondo.
Meh,

612

Per gli utenti che vogliono solo inserire sfondo, icona-immagine e testo in uno Button da file diversi: impostare su uno Buttonsfondo, attributi disegnabili in alto / in basso / in ordine di gravità / a sinistra e di riempimento .

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

Per una disposizione più sofisticata puoi anche usare RelativeLayout(o qualsiasi altro layout) e renderlo cliccabile.

Tutorial: ottimo tutorial che copre entrambi i casi: http://izvornikod.com/Blog/tabid/82/EntryId/8/Creating-Android-button-with-image-and-text-using-relative-layout.aspx


70
Per fare ciò, utilizzare a livello di codice b.setCompoundDrawablesWithIntrinsicBound(null,R.drawable.home_icon_test,null,null)anziché android:drawableTope b.setPadding(0,32,0,0)invece di android:paddingTop.
Alex Jasmin,

3
L'uso di un layout come pulsante è in realtà un approccio abbastanza flessibile.
sstn

2
Sostituisci null con 0 se stai utilizzando gli ID risorse per i tuoi disegni estraibili
eseguito

1
Come posso ridimensionare l'immagine di backgournd per adattarla al pulsante?
Alston,

@Stallman Esiste una soluzione xml e basata sul codice per il ridimensionamento: stackoverflow.com/questions/8223936/…
OneWorld

346

C'è una soluzione molto migliore per questo problema.

Basta prendere un normale Buttone usare drawableLeftgli gravityattributi e.

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

In questo modo si ottiene un pulsante che visualizza un'icona nella parte sinistra del pulsante e il testo nella parte destra dell'icona centrata verticalmente .


2
Un problema si verifica con questa soluzione se si sceglie di avere un colore di sfondo sul pulsante (che è probabilmente in questo caso). Quindi non ci sarà alcuna risposta grafica al clic o alla selezione. Puoi scrivere un selettore per gestirlo, ma non otterrai i colori predefiniti dei telefoni.
Vanja,

9
Volevo solo aggiungere che la proprietà Padding Drawable è molto utile se si utilizza questa soluzione.
Nikola Malešević,

5
C'è un modo per impostare l'altezza e la larghezza dell'icona di disegno in XML?
penguru,

18
Questa è un'ottima soluzione ed è anche ufficialmente approvata sul sito degli sviluppatori Android: developer.android.com/guide/topics/ui/controls/button.html
twaddington

3
se il pulsante è grande e il testo è lungo e variabile, sembra brutto: icona al massimo a sinistra e testo da qualche parte nel mezzo

67

inserisci qui la descrizione dell'immagine

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

4
Una soluzione semplice e sbagliata. Solo per allineamento a sinistra.
CoolMind

2
@ CoolMind Sto spiegando solo per l'immagine sopra che ho allegato .. se vuoi allineare a destra usa drawableRight
Dhina k

Non stavo nemmeno pensando di farlo fino a quando non ho letto questa risposta. Funziona come un incantesimo!
sud007,

59

Basta usare un LinearLayout e fingere che sia un Button- impostazione backgrounde cliccabile è la chiave:

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

1
Come aggiungere l'effetto cliccato?
franco il

3
La migliore risposta, in questo modo gestisci il 100% dell'aspetto e non devi attaccare l'icona a un bordo.
Climbatize

franco, aggiungi android:onClickalla tua vista
Giora Guttsait

43

basta sostituire

android:background="@drawable/icon"

con

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

izz un bel trucco ..;)


21

Ho adottato un approccio diverso da quelli qui indicati e funziona davvero bene, quindi volevo condividerlo.

Sto usando uno stile per creare un pulsante personalizzato con immagine a sinistra e testo al centro-destra. Segui i 4 "semplici passaggi" di seguito:

I. Crea le tue 9 patch utilizzando almeno 3 diversi file PNG e lo strumento che hai in: /YOUR_OWN_PATH/android-sdk-mac_x86/tools/./draw9patch. Dopo questo dovresti avere:

button_normal.9.png, button_focused.9.png e button_pressed.9.png

Quindi scaricare o creare un'icona PNG 24x24.

ic_your_icon.png

Salva tutto nella cartella / nel tuo progetto Android.

II. Crea un file XML chiamato button_selector.xml nel tuo progetto nella cartella drawable /. Gli stati dovrebbero essere così:

<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. Vai alla cartella valori / e apri o crea il file styles.xml e crea il seguente codice 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 è uno "stile figlio" perché estende ButtonNormalText (lo "stile principale").

Nota che cambiando il drawableLeft nello stile ButtonNormalTextWithIcon, in drawableRight, drawableTop o drawableBottom puoi posizionare l'icona in un'altra posizione rispetto al testo.

IV. Vai al layout / cartella in cui hai il tuo XML per l'interfaccia utente e vai al pulsante in cui vuoi applicare lo stile e farlo apparire così:

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

E ... voilà! Hai il tuo pulsante con un'immagine sul lato sinistro.

Per me, questo è il modo migliore per farlo! perché in questo modo è possibile gestire le dimensioni del testo del pulsante separatamente dall'icona che si desidera visualizzare e utilizzare lo stesso sfondo disegnabile per più pulsanti con icone diverse rispettando le Linee guida dell'interfaccia utente Android utilizzando gli stili.

Puoi anche creare un tema per la tua app e aggiungere lo "stile principale" in modo che tutti i pulsanti abbiano lo stesso aspetto e applicare lo "stile figlio" con l'icona solo dove ti serve.


Buon lavoro. Stavo usando un approccio di visualizzazione FrameLayout con ImageView e TextView all'interno, ma questo approccio è più bello.
pilcrowpipe il

Approccio fantastico. Facebook SDK (versione 3) utilizza lo stesso approccio per il pulsante di accesso
Someone Somewhere

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

11

Puoi usare drawableTop(anche drawableLeft, ecc.) Per l'immagine e impostare il testo sotto l'immagine aggiungendo ilgravity 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" />

11

Aggiornamento importante

Non usare normale, android:drawableLeftecc ... con drawable vettoriali, altrimenti andrà in crash nelle versioni API inferiori . (L'ho affrontato nell'app live)

Per il disegno vettoriale

Se si utilizza il disegno vettoriale, è necessario

  • Sei migrato su AndroidX? in caso contrario devi prima migrare su AndroidX. È molto semplice, vedi cos'è androidx e come migrare?
  • È stato rilasciato nella versione 1.1.0-alpha01, quindi la versione di appcompat dovrebbe essere almeno 1.1.0-alpha01. L'ultima versione attuale è 1.1.0-alpha02, utilizzare le ultime versioni per una migliore affidabilità, vedere le note di rilascio - collegamento .

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

  • Usa AppCompatTextView/ AppCompatButton/AppCompatEditText

  • Usa app:drawableLeftCompat, app:drawableTopCompat, app:drawableRightCompat, app:drawableBottomCompat, app:drawableStartCompateapp:drawableEndCompat

Per il disegno normale

Se non hai bisogno di un disegno vettoriale, puoi farlo

  • uso android:drawableLeft, android:drawableRight, android:drawableBottom,android:drawableTop
  • È possibile utilizzare sia normale TextView, Buttone EditTexto AppCompatclassi.

Puoi ottenere un output come di seguito:

produzione


Sto usando lo xmlns:app="http://schemas.android.com/apk/res-auto"spazio dei nomi e non vedo quelle cose compatibili con l'app.
Dale

1
@Dale il tuo spazio dei nomi è corretto, ho aggiornato la mia risposta, vedi di For vector drawablenuovo punto.
Khemraj,

@Khemraj Come stai centrando sia il disegno che il testo nella vista singola (sia TextView o Button o qualcos'altro) come mostrato nell'immagine che hai allegato?
Ambar Jain,

7

Probabilmente la mia soluzione è adatta a molti utenti, lo spero.

Quello che sto suggerendo è rendere TextView con il tuo stile. Funziona perfettamente per me e ha tutte le caratteristiche, come un pulsante.

Prima di tutto, facciamo lo stile del pulsante, che puoi usare ovunque ... Sto 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>

In secondo luogo, consente di creare un pulsante di visualizzazione del testo.

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

E questo è un risultato. Quindi dai uno stile al tuo pulsante personalizzato con qualsiasi colore o qualsiasi altra proprietà e margine. In bocca al lupo

inserisci qui la descrizione dell'immagine


Anche se devo ancora testare il tuo codice poiché l'approccio sembra essere corretto, ma non capisco il motivo di avere l'effetto hover in un'app mobile.
Mohammed Akhtar Zuberi,

Ho creato l'effetto hover per la mia app e durante la creazione di quell'app avevo bisogno dell'effetto hover. Ma dipende da te :) Puoi eliminare l'effetto hover se non è necessario.
Jevgenij Kononov,

Ho votato a favore della tua risposta in quanto è un ottimo approccio. Il mio unico punto è su un'interfaccia mobile come puoi passare il mouse?
Mohammed Akhtar Zuberi,

Oo ... Adesso vedo ..: D Sì, hai ragione. È impossibile. Tale effetto hover è principalmente per l'effetto di pressione. Solo nome errato per la classe xml
Jevgenij Kononov


5

Questo codice funziona perfettamente per me

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

Ho provato il tuo codice .. funziona ma il problema principale del tuo codice è che hai un set di pulsanti, con dimensioni del testo diverse in ciascun pulsante. Il layout verrà spostato. Quindi ogni posizione dell'immagine del pulsante sarà in un posto diverso. Mentre dovrebbe essere dritto al centro. Questo è ciò che accade con il pulsante.
Jevgenij Kononov,

0

Puoi usare questo:

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

nel senso che ho messo un'immagine come backgrounde anche aggiunto del testo ..!


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

Oppure puoi programmare:

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

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

Questa non è una risposta giusta perché la vista Immagine non supporta il testo
Muhammed Fasil,
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.