Android: menggabungkan teks & gambar pada Tombol atau ImageButton

540

Saya mencoba memiliki gambar (sebagai latar belakang) pada tombol dan menambahkan secara dinamis, tergantung pada apa yang terjadi selama waktu berjalan, beberapa teks di atas / di atas gambar.

Jika saya menggunakan, ImageButtonsaya bahkan tidak memiliki kemungkinan untuk menambahkan teks. Jika saya menggunakan Buttonsaya dapat menambahkan teks tetapi hanya mendefinisikan gambar dengan android:drawableBottomdan atribut XML yang sama seperti yang didefinisikan di sini .

Namun atribut ini hanya menggabungkan teks & gambar dalam dimensi x dan y, artinya saya dapat menggambar gambar di sekitar teks saya, tetapi tidak di bawah / di bawah teks saya (dengan sumbu z didefinisikan sebagai keluar dari tampilan).

Ada saran tentang cara untuk melakukan hal ini? Satu ide adalah memperluas Buttonatau ImageButtonmenimpa draw()-metode. Tetapi dengan tingkat pengetahuan saya saat ini, saya tidak benar-benar tahu bagaimana melakukan ini (rendering 2D). Mungkin seseorang dengan pengalaman lebih tahu solusi atau setidaknya beberapa petunjuk untuk memulai?

znq
sumber
gunakan 9Patch, solusi cerdas
Kaveh Garshasp
hi @Charu ක periksa ini jika Anda dapat stackoverflow.com/questions/42968587/...
Mohamed Rihan

Jawaban:

205

Anda dapat memanggil setBackground()a Buttonuntuk mengatur latar belakang tombol.

Teks apa pun akan muncul di atas latar belakang.

Jika Anda mencari sesuatu yang serupa di xml ada: android:backgroundatribut yang berfungsi dengan cara yang sama.

m_vitaly
sumber
49
Jika Anda menggunakan rute ini, Anda tidak ingin hanya menggunakan gambar sederhana untuk latar belakang. Gunakan StateListDrawable (biasanya melalui file XML <selector> di res / drawable /), sehingga Anda dapat menentukan latar belakang untuk berbagai status (normal, ditekan, fokus, dinonaktifkan, dll.).
CommonsWare
Setuju dengan Anda, cari pertanyaan ini dan jawaban saya: stackoverflow.com/questions/1533038/…
m_vitaly
1
Bodoh sekali. Bagaimana saya bisa melewatkan itu di dokumentasi. Terima kasih atas jawaban cepat dan juga petunjuk dengan <selektor>. Itu sesuatu yang pasti ingin saya terapkan di masa depan.
znq
3
Itu tidak berfungsi dengan benar pada versi ICS 4.0+, gambar membentang. Saya menggunakan TextView dengan latar belakang.
meh
612

Untuk pengguna yang hanya ingin meletakkan Background, Ikon-Gambar dan Teks dalam satu Button dari file yang berbeda: Atur pada Buttonlatar belakang, drawableTop / Bottom / Rigth / Kiri dan atribut padding .

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

Untuk pengaturan yang lebih canggih, Anda juga dapat menggunakan RelativeLayout(atau tata letak lainnya) dan membuatnya dapat diklik.

Tutorial: Tutorial hebat yang mencakup kedua kasus: http://izvornikod.com/Blog/tabid/82/EntryId/8/Creating-Android-button-with-image-and-text-using-relative-layout.aspx

Satu dunia
sumber
70
Untuk melakukan ini secara terprogram gunakan b.setCompoundDrawablesWithIntrinsicBound(null,R.drawable.home_icon_test,null,null)alih- alih android:drawableTopdan b.setPadding(0,32,0,0)bukan android:paddingTop.
Alex Jasmin
3
Menggunakan tata letak sebagai tombol sebenarnya adalah pendekatan yang cukup fleksibel.
sstn
2
Cukup ganti nol dengan 0 jika Anda menggunakan id sumber daya untuk drawables Anda
Berlangsung
1
Bagaimana saya bisa skala gambar backgournd agar sesuai dengan tombol?
Alston
@Stallman Ada solusi berbasis kode dan berbasis xml untuk penskalaan: stackoverflow.com/questions/8223936/…
OneWorld
346

Ada solusi yang jauh lebih baik untuk masalah ini.

Hanya mengambil normal Buttondan menggunakan drawableLeftdan gravityatribut.

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

Dengan cara ini Anda mendapatkan tombol yang menampilkan ikon di sisi kiri tombol dan teks di situs kanan ikon yang berpusat vertikal .

schlingel
sumber
2
Masalah terjadi dengan solusi ini jika Anda memilih untuk memiliki warna latar belakang pada tombol (yang mungkin dalam kasus ini). Maka tidak akan ada respons grafis untuk klik atau seleksi. Anda dapat menulis pemilih untuk menangani ini, tetapi kemudian Anda tidak akan mendapatkan warna default ponsel.
Vanja
9
Hanya ingin menambahkan bahwa properti Drawable padding sangat berguna jika solusi ini digunakan.
Nikola Malešević
5
Apakah ada cara untuk mengatur tinggi & lebar untuk ikon yang dapat ditarik dalam xml?
penguru
18
Ini adalah solusi hebat dan juga secara resmi disetujui di situs pengembang Android: developer.android.com/guide/topics/ui/controls/button.html
twaddington
3
jika tombolnya besar dan teksnya variabel panjang, daripada terlihat jelek: ikon paling kiri dan teks di suatu tempat di tengah
67

masukkan deskripsi gambar di sini

     <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
sumber
4
Solusi sederhana dan salah. Hanya untuk perataan kiri.
CoolMind
2
@ CoolMind Saya menjelaskan hanya untuk gambar di atas yang saya lampirkan .. jika Anda ingin menggunakan penyelarasan yang benar drawableRight
Dhina k
Saya bahkan tidak berpikir untuk melakukan ini sampai saya membaca jawaban ini. Ini bekerja seperti pesona!
sud007
59

Cukup gunakan LinearLayout dan anggap itu Button- pengaturan backgrounddan dapat diklik adalah kuncinya:

<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
sumber
1
Bagaimana cara menambahkan efek yang diklik?
frankish
3
Jawaban terbaik, dengan cara ini Anda mengelola 100% tampilan dan nuansa dan Anda tidak harus menempel ikon ke perbatasan.
Climbatize
jujur, tambahkan android:onClickke pandangan Anda
Giora Guttsait
43

ganti saja

android:background="@drawable/icon"

dengan

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

izz trik yang cukup bagus ..;)

CMA
sumber
21

Saya mengambil pendekatan yang berbeda dari yang dinyatakan di sini, dan itu bekerja dengan sangat baik, jadi saya ingin membagikannya.

Saya menggunakan Style untuk membuat tombol kustom dengan gambar di sebelah kiri dan teks di kanan-tengah. Cukup ikuti 4 "langkah mudah" di bawah:

I. Buat 9 tambalan Anda menggunakan setidaknya 3 file PNG berbeda dan alat yang Anda miliki di: /YOUR_OWN_PATH/android-sdk-mac_x86/tools/./draw9patch. Setelah ini, Anda harus memiliki:

button_normal.9.png, button_focused.9.png dan button_pressed.9.png

Kemudian unduh atau buat ikon PNG 24x24.

ic_your_icon.png

Simpan semua dalam folder / drawable di proyek Android Anda.

II Buat file XML bernama button_selector.xml di proyek Anda di bawah drawable / folder. Negara harus seperti ini:

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

AKU AKU AKU. Buka nilai / folder dan buka atau buat file styles.xml dan buat kode XML berikut:

<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 adalah "gaya anak" karena memperluas ButtonNormalText ("gaya induk").

Perhatikan bahwa mengubah drawableLeft dalam gaya ButtonNormalTextWithIcon menjadi drawableRight, drawableTop atau drawableBottom Anda dapat menempatkan ikon di posisi lain sehubungan dengan teks.

IV. Buka tata letak / folder tempat Anda memiliki XML untuk UI dan buka Tombol tempat Anda ingin menerapkan gaya dan buat tampilannya seperti ini:

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

Dan ... voila! Anda mendapatkan tombol Anda dengan gambar di sebelah kiri.

Bagi saya, ini adalah cara yang lebih baik untuk melakukannya! karena melakukannya dengan cara ini Anda dapat mengelola ukuran teks tombol secara terpisah dari ikon yang ingin Anda tampilkan dan menggunakan latar belakang yang sama untuk beberapa tombol dengan ikon berbeda yang menghormati Pedoman Android UI menggunakan gaya.

Anda juga dapat membuat tema untuk Aplikasi Anda dan menambahkan "gaya induk" ke dalamnya sehingga semua tombol terlihat sama, dan menerapkan "gaya anak" dengan ikon hanya di mana Anda membutuhkannya.

Oscar Salguero
sumber
Kerja bagus. Saya menggunakan pendekatan tampilan FrameLayout dengan ImageView dan TextView di dalamnya, tetapi pendekatan ini lebih baik.
pilcrowpipe
Pendekatan yang luar biasa. Facebook SDK (versi 3) mengambil pendekatan yang sama untuk tombol masuk
Seseorang di suatu tempat
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
sumber
11

Anda dapat menggunakan drawableTop(juga drawableLeft, dll) untuk gambar dan mengatur teks di bawah gambar dengan menambahkangravity 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
sumber
11

Pembaruan Penting

Jangan gunakan normal android:drawableLeftdll ... dengan drawable vektor, kalau tidak akan crash di versi API yang lebih rendah . (Saya telah menghadapinya di aplikasi langsung)

Untuk digambar vektor

Jika Anda menggunakan gambar vektor, maka Anda harus

  • Sudahkah Anda bermigrasi ke AndroidX? jika tidak, Anda harus bermigrasi ke AndroidX terlebih dahulu. Sangat sederhana, lihat apa itu androidx, dan bagaimana cara bermigrasi?
  • Itu dirilis dalam versi 1.1.0-alpha01, jadi versi appcompat harus setidaknya 1.1.0-alpha01. Versi terbaru saat ini adalah 1.1.0-alpha02, gunakan versi terbaru untuk keandalan yang lebih baik, lihat catatan rilis - tautan .

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

  • Gunakan AppCompatTextView/ AppCompatButton/AppCompatEditText

  • Gunakan app:drawableLeftCompat, app:drawableTopCompat, app:drawableRightCompat, app:drawableBottomCompat, app:drawableStartCompatdanapp:drawableEndCompat

Untuk drawable biasa

Jika Anda tidak perlu digambar vektor, maka Anda bisa

  • penggunaan android:drawableLeft, android:drawableRight, android:drawableBottom,android:drawableTop
  • Anda dapat menggunakan kelas reguler TextView, Button& EditTextatau AppCompat.

Anda dapat mencapai Output seperti di bawah ini -

keluaran

Khemraj
sumber
Saya menggunakan xmlns:app="http://schemas.android.com/apk/res-auto"namespace dan tidak melihat hal-hal yang kompatibel dengan aplikasi itu.
Dale
1
@Dale namespace Anda sudah benar, saya telah memperbarui jawaban saya, lihat For vector drawablepoin lagi.
Khemraj
@Khemraj Bagaimana Anda memusatkan gambar dan teks dalam satu tampilan (baik TextView atau Button atau yang lainnya) seperti yang ditampilkan pada gambar yang Anda lampirkan?
Ambar Jain
7

Mungkin solusi saya cocok untuk banyak pengguna, saya harap begitu.

Yang saya sarankan adalah membuat TextView dengan gaya Anda. Ini berfungsi dengan baik untuk saya, dan telah mendapatkan semua fitur, seperti tombol.

Pertama-tama mari kita buat gaya tombol, yang dapat Anda gunakan di mana-mana ... Saya membuat 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>

Kedua, Mari kita buat tombol textview.

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

Dan ini hasilnya. Kemudian gaya tombol kustom Anda dengan warna atau properti dan margin lainnya. Semoga berhasil

masukkan deskripsi gambar di sini

Jevgenij Kononov
sumber
Meskipun saya belum menguji kode Anda karena pendekatannya tampaknya benar, tetapi saya tidak mengerti alasan memiliki efek melayang di aplikasi seluler.
Mohammed Akhtar Zuberi
Saya telah membuat efek melayang untuk aplikasi saya, dan selama pembangunan aplikasi itu saya membutuhkan efek melayang. Tapi terserah Anda :) Anda dapat menghapus efek hover jika tidak perlu.
Jevgenij Kononov
Saya telah memilih jawaban Anda karena ini adalah pendekatan yang sangat bagus. Satu-satunya poin saya adalah pada antarmuka seluler bagaimana Anda bisa mengarahkan?
Mohammed Akhtar Zuberi
Oo ... Saya mengerti sekarang ..: D Yeap, Anda benar. Itu tidak mungkin. Efek hover itu sebagian besar untuk efek menekan. Nama yang tidak tepat untuk kelas xml
Jevgenij Kononov
5

Kode ini berfungsi dengan baik untuk saya

<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
sumber
Saya telah mencoba kode Anda .. itu berfungsi tetapi masalah utama dari kode Anda jika Anda telah menetapkan tombol, dengan ukuran teks yang berbeda di setiap tombol. Tata letak Anda akan digeser. Jadi setiap posisi gambar tombol akan berada di tempat yang berbeda. Sementara itu harus lurus di tengah. Inilah yang terjadi dengan tombol.
Jevgenij Kononov
0

Anda bisa menggunakan ini:

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

karena saya telah menempatkan gambar backgrounddan juga menambahkan teks ..!

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

Atau Anda dapat secara terprogram:

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
sumber
-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
sumber
Ini bukan jawaban yang tepat karena tampilan gambar tidak mendukung teks
Muhammed Fasil