Android: Kombinieren von Text und Bild auf einem Button oder ImageButton

540

Ich versuche, ein Bild (als Hintergrund) auf einer Schaltfläche zu haben und dynamisch, abhängig davon, was zur Laufzeit passiert, Text über / über dem Bild hinzuzufügen.

Wenn ich benutze, ImageButtonhabe ich nicht einmal die Möglichkeit, Text hinzuzufügen. Wenn ich verwende, Buttonkann ich Text hinzufügen, aber nur ein Bild mit android:drawableBottomund ähnlichen XML-Attributen definieren, wie hier definiert .

Diese Attribute kombinieren jedoch nur Text und Bild in x- und y-Dimensionen, was bedeutet, dass ich ein Bild um meinen Text zeichnen kann, jedoch nicht unter / unter meinem Text (wobei die Z-Achse so definiert ist, dass sie aus der Anzeige kommt).

Irgendwelche Vorschläge dazu? Eine Idee wäre, die Methode entweder zu erweitern Buttonoder zu ImageButtonüberschreiben draw(). Aber mit meinem derzeitigen Kenntnisstand weiß ich nicht wirklich, wie das geht (2D-Rendering). Vielleicht kennt jemand mit mehr Erfahrung eine Lösung oder zumindest einige Hinweise, um zu beginnen?

znq
quelle
Verwenden Sie 9Patch, intelligente Lösung
Kaveh Garshasp
hi @Charu ක bitte überprüfen Sie dies, wenn Sie stackoverflow.com/questions/42968587/…
Mohamed Rihan

Antworten:

205

Sie können rufen setBackground()auf ein Buttonden Hintergrund der Taste.

Jeder Text wird über dem Hintergrund angezeigt.

Wenn Sie nach etwas Ähnlichem in XML suchen, gibt es: android:backgroundAttribut, das auf die gleiche Weise funktioniert.

m_vitaly
quelle
49
Wenn Sie diesen Weg gehen, möchten Sie nicht nur ein einfaches Zeichen für den Hintergrund verwenden. Verwenden Sie eine StateListDrawable (normalerweise über die XML-Datei <selector> in res / drawable /), damit Sie Hintergründe für die verschiedenen Status definieren können (normal, gedrückt, fokussiert, deaktiviert usw.).
CommonsWare
Stimmen Sie zu, suchen Sie nach dieser Frage und meiner Antwort: stackoverflow.com/questions/1533038/…
m_vitaly
1
Wie blöd. Wie konnte ich das in der Dokumentation übersehen haben. Vielen Dank für die schnelle Antwort und auch den Hinweis mit dem <Selektor>. Das möchte ich definitiv in Zukunft umsetzen.
ZnQ
3
Bei ICS 4.0+ Versionen funktioniert es nicht richtig, das Bild wird gedehnt. Ich habe eine Textansicht mit Hintergrund verwendet.
meh
612

Für Benutzer, die nur Hintergrund, Symbol -Bild und TextButton aus verschiedenen Dateien in eine Datei Buttoneinfügen möchten : Auf Hintergrund setzen, DrawableTop / Bottom / Rigth / Left- und Padding- Attribute.

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

Für eine anspruchsvollere Anordnung können Sie auch RelativeLayout(oder ein anderes Layout) verwenden und es anklickbar machen.

Tutorial: Tolles Tutorial, das beide Fälle abdeckt: http://izvornikod.com/Blog/tabid/82/EntryId/8/Creating-Android-button-with-image-and-text-using-relative-layout.aspx

Eine Welt
quelle
70
Verwenden Sie dazu programmgesteuert b.setCompoundDrawablesWithIntrinsicBound(null,R.drawable.home_icon_test,null,null)anstelle von android:drawableTopund b.setPadding(0,32,0,0)anstelle von android:paddingTop.
Alex Jasmin
3
Die Verwendung eines Layouts als Schaltfläche ist eigentlich ein recht flexibler Ansatz.
sstn
2
Ersetzen Sie einfach null durch 0, wenn Sie Ressourcen-IDs für Ihre Drawables verwenden
Ran
1
Wie kann ich das Hintergrundbild so skalieren, dass es auf die Schaltfläche passt?
Alston
@Stallman Es gibt eine XML-basierte und Code-basierte Lösung für die Skalierung: stackoverflow.com/questions/8223936/…
OneWorld
346

Es gibt eine viel bessere Lösung für dieses Problem.

Nehmen Sie einfach eine normale Buttonund verwenden Sie die drawableLeftund die gravityAttribute.

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

Auf diese Weise erhalten Sie eine Schaltfläche, die ein Symbol auf der linken Seite der Schaltfläche und den Text an der rechten Stelle des Symbols vertikal zentriert anzeigt .

schlingel
quelle
2
Bei dieser Lösung tritt ein Problem auf, wenn Sie eine Hintergrundfarbe auf der Schaltfläche ausgewählt haben (was in diesem Fall wahrscheinlich ist). Dann erfolgt keine grafische Antwort auf Klick oder Auswahl. Sie können einen Selektor schreiben, um dies zu handhaben, aber dann erhalten Sie nicht die Standardfarben des Telefons.
Vanja
9
Ich wollte nur hinzufügen, dass die Eigenschaft Drawable Padding sehr nützlich ist, wenn diese Lösung verwendet wird.
Nikola Malešević
5
Gibt es eine Möglichkeit, Höhe und Breite für das zeichnbare Symbol in XML festzulegen?
Penguru
18
Dies ist eine großartige Lösung und wird auch offiziell auf der Android-Entwicklerseite
empfohlen
3
Wenn die Schaltfläche groß und der Text variabel lang ist, sieht sie hässlich aus: Symbol höchstens links und Text irgendwo in der Mitte
67

Geben Sie hier die Bildbeschreibung ein

     <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" />
Dhina k
quelle
4
Eine einfache und falsche Lösung. Nur zur Linksausrichtung.
CoolMind
2
@ CoolMind Ich erkläre nur für das obige Bild, das ich angehängt habe. Wenn Sie richtig ausrichten möchten, verwenden Sie drawableRight
Dhina k
Ich habe nicht einmal daran gedacht, bis ich diese Antwort gelesen habe. Das funktioniert wie ein Zauber!
sud007
58

Verwenden Sie einfach ein LinearLayout und tun Sie so, als wäre es eine ButtonEinstellung backgroundund anklickbar ist der Schlüssel:

<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>
Kieran
quelle
1
Wie füge ich einen angeklickten Effekt hinzu?
Frankish
3
Beste Antwort: Auf diese Weise verwalten Sie 100% des Erscheinungsbilds und müssen das Symbol nicht an einen Rand kleben.
Climbatize
Frankish, fügen Sie android:onClickIhrer Ansicht hinzu
Giora Guttsait
43

einfach ersetzen

android:background="@drawable/icon"

mit

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

izz ein ziemlich guter Trick ..;)

CMA
quelle
21

Ich habe einen anderen Ansatz gewählt als hier angegeben, und er funktioniert wirklich gut, deshalb wollte ich ihn teilen.

Ich verwende einen Stil, um eine benutzerdefinierte Schaltfläche mit Bild links und Text in der Mitte rechts zu erstellen. Befolgen Sie einfach die folgenden 4 "einfachen Schritte":

I. Erstellen Sie Ihre 9 Patches mit mindestens 3 verschiedenen PNG-Dateien und dem Tool, das Sie unter: /YOUR_OWN_PATH/android-sdk-mac_x86/tools/./draw9patch haben. Danach sollten Sie haben:

button_normal.9.png, button_focused.9.png und button_pressed.9.png

Laden Sie dann ein 24x24 PNG-Symbol herunter oder erstellen Sie es.

ic_your_icon.png

Speichern Sie alles im Zeichen- / Ordner Ihres Android-Projekts.

II. Erstellen Sie in Ihrem Projekt eine XML-Datei mit dem Namen button_selector.xml unter dem Ordner drawable /. Die Staaten sollten so sein:

<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. Gehen Sie zum Ordner values ​​/ und öffnen oder erstellen Sie die Datei styles.xml und erstellen Sie den folgenden XML-Code:

<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 ist ein "untergeordneter Stil", da es ButtonNormalText (den "übergeordneten Stil") erweitert.

Beachten Sie, dass Sie das Symbol durch Ändern von drawableLeft im ButtonNormalTextWithIcon-Stil in drawableRight, drawableTop oder drawableBottom an einer anderen Position in Bezug auf den Text platzieren können.

IV. Gehen Sie zu dem Layout / Ordner, in dem Sie Ihr XML für die Benutzeroberfläche haben, und gehen Sie zu der Schaltfläche, in der Sie den Stil anwenden möchten, und lassen Sie ihn so aussehen:

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

Und ... voilà! Sie haben Ihren Knopf mit einem Bild auf der linken Seite.

Für mich ist das der bessere Weg! Auf diese Weise können Sie die Textgröße der Schaltfläche getrennt von dem Symbol, das Sie anzeigen möchten, verwalten und denselben Hintergrund verwenden, der für mehrere Schaltflächen mit unterschiedlichen Symbolen gezeichnet werden kann. Beachten Sie dabei die Richtlinien für die Android-Benutzeroberfläche mithilfe von Stilen.

Sie können auch ein Thema für Ihre App erstellen und den "übergeordneten Stil" hinzufügen, damit alle Schaltflächen gleich aussehen, und den "untergeordneten Stil" mit dem Symbol nur dort anwenden, wo Sie ihn benötigen.

Oscar Salguero
quelle
Gute Arbeit. Ich habe einen FrameLayout-Ansichtsansatz mit einer ImageView und einer TextView verwendet, aber dieser Ansatz ist besser.
Pilcrowpipe
Super Ansatz. Das Facebook SDK (Version 3) verfolgt den gleichen Ansatz für den Login-Button
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"         
        />   
Salman Khursheed Khaleeqi
quelle
11

Sie können drawableTop(auch drawableLeftusw.) für das Bild verwenden und Text unter dem Bild festlegen, indem Sie das hinzufügengravity 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" />
Kalai.G
quelle
11

Wichtiges Update

Verwenden Sie kein normales android:drawableLeftetc ... mit Vektor-Drawables, da es sonst in niedrigeren API-Versionen abstürzt . (Ich habe es in der Live-App konfrontiert)

Für Vektor zeichnbar

Wenn Sie Vector Drawable verwenden, müssen Sie

  • Haben Sie auf AndroidX migriert? Wenn nicht, müssen Sie zuerst auf AndroidX migrieren. Es ist sehr einfach zu sehen, was AndroidX ist und wie man migriert?
  • Es wurde in der Version veröffentlicht 1.1.0-alpha01, daher sollte die Appcompat-Version mindestens verfügbar sein 1.1.0-alpha01. Aktuelle neueste Version ist 1.1.0-alpha02, verwenden Sie die neuesten Versionen für eine bessere Zuverlässigkeit, siehe Versionshinweise - Link .

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

  • Verwenden Sie AppCompatTextView/ AppCompatButton/AppCompatEditText

  • Verwenden Sie app:drawableLeftCompat, app:drawableTopCompat, app:drawableRightCompat, app:drawableBottomCompat, app:drawableStartCompatundapp:drawableEndCompat

Zum regelmäßigen Zeichnen

Wenn Sie keinen Vektor zum Zeichnen benötigen, können Sie dies tun

  • Verwendung android:drawableLeft, android:drawableRight, android:drawableBottom,android:drawableTop
  • Sie können entweder regelmäßig verwenden TextView, Button& EditTextoder AppCompatKlassen.

Sie können eine Ausgabe wie unten erzielen -

Ausgabe

Khemraj
quelle
Ich verwende den xmlns:app="http://schemas.android.com/apk/res-auto"Namespace und sehe diese App-kompatiblen Dinge nicht.
Dale
1
@ Dale Ihr Namespace ist korrekt, ich habe meine Antwort aktualisiert, siehe For vector drawablePunkt noch einmal.
Khemraj
@Khemraj Wie zentrieren Sie sowohl Zeichen- als auch Text in der Einzelansicht (entweder eine Textansicht oder eine Schaltfläche oder etwas anderes), wie in dem angehängten Bild angezeigt?
Ambar Jain
7

Wahrscheinlich wird meine Lösung für viele Benutzer geeignet sein, ich hoffe es.

Ich schlage vor, TextView mit Ihrem Stil zu erstellen. Es funktioniert perfekt für mich und hat alle Funktionen, wie ein Knopf.

Lassen Sie uns zunächst einen Schaltflächenstil erstellen, den Sie überall verwenden können ... Ich erstelle 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>

Zweitens erstellen wir eine Textansicht-Schaltfläche.

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

Und das ist ein Ergebnis. Gestalten Sie dann Ihre benutzerdefinierte Schaltfläche mit beliebigen Farben oder anderen Eigenschaften und Rändern. Viel Glück

Geben Sie hier die Bildbeschreibung ein

Jevgenij Kononov
quelle
Ich muss Ihren Code zwar noch testen, da der Ansatz korrekt zu sein scheint, aber ich verstehe den Grund für den Hover-Effekt in einer mobilen App nicht.
Mohammed Akhtar Zuberi
Ich habe einen Hover-Effekt für meine App erstellt und während dieses App-Builds brauchte ich einen Hover-Effekt. Aber es liegt an Ihnen :) Sie können den Hover-Effekt löschen, wenn dies nicht erforderlich ist.
Jevgenij Kononov
Ich habe Ihre Antwort abgelehnt, da dies ein sehr guter Ansatz ist. Mein einziger Punkt ist auf einer mobilen Oberfläche, wie können Sie schweben?
Mohammed Akhtar Zuberi
Oo ... ich verstehe jetzt ..: D Ja, du hast recht. Es ist unmöglich. Dieser Schwebeeffekt dient hauptsächlich zum Drücken. Nur falscher Name für XML-Klasse
Jevgenij Kononov
5

Dieser Code funktioniert perfekt für mich

<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>
eyal
quelle
Ich habe Ihren Code ausprobiert. Es funktioniert, aber das Hauptproblem Ihres Codes, wenn Sie Schaltflächen mit unterschiedlichen Textgrößen in jeder Schaltfläche haben. Ihr Layout wird verschoben. Jede Bildposition der Schaltfläche befindet sich also an einer anderen Stelle. Während es gerade in der Mitte sein sollte. Dies ist, was mit der Taste passiert.
Jevgenij Kononov
0

Sie können dies verwenden:

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

darin habe ich ein bild als backgroundeingefügt und auch text hinzugefügt ..!

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

Oder Sie können programmgesteuert:

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
Kerim FIRAT
quelle
-4
    <ImageView
        android:id="@+id/iv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        android:src="@drawable/temp"
        />
Jayesh Prajapati
quelle
Dies ist keine richtige Antwort, da die Bildansicht keinen Text unterstützt
Muhammed Fasil