Android: การรวมข้อความและรูปภาพบนปุ่มหรือ ImageButton


540

ฉันพยายามที่จะมีภาพ (เป็นพื้นหลัง) ที่ปุ่มและเพิ่มแบบไดนามิกขึ้นอยู่กับสิ่งที่เกิดขึ้นในช่วงเวลาทำงานข้อความบางข้อความด้านบน / เหนือภาพ

ถ้าฉันใช้ImageButtonฉันไม่มีโอกาสที่จะเพิ่มข้อความ หากฉันใช้Buttonฉันสามารถเพิ่มข้อความกำหนด แต่เพียงภาพที่มีandroid:drawableBottomและแอตทริบิวต์ XML ที่คล้ายกันตามที่กำหนดไว้ที่นี่

อย่างไรก็ตามคุณลักษณะเหล่านี้รวมข้อความและรูปภาพในขนาด x และ y เท่านั้นซึ่งหมายความว่าฉันสามารถวาดภาพที่อยู่รอบข้อความของฉันได้ แต่ไม่ต่ำกว่า / ใต้ข้อความของฉัน (โดยมีแกน z กำหนดว่าออกมาจากหน้าจอ)

ข้อเสนอแนะใด ๆ เกี่ยวกับวิธีการทำเช่นนี้? หนึ่งความคิดที่จะให้ทั้งขยายButtonหรือImageButtonและแทนที่draw()-method แต่ด้วยระดับความรู้ปัจจุบันของฉันฉันไม่รู้วิธีการทำสิ่งนี้จริงๆ (การเรนเดอร์แบบ 2D) อาจเป็นคนที่มีประสบการณ์มากขึ้นรู้วิธีแก้ปัญหาหรืออย่างน้อยก็มีพอยน์เตอร์ให้เริ่ม?


ใช้ 9Patch โซลูชันอัจฉริยะ
Kaveh Garshasp

สวัสดี @Charu කโปรดตรวจสอบสิ่งนี้หากคุณสามารถstackoverflow.com/questions/42968587/…
Mohamed Rihan

คำตอบ:


205

คุณสามารถโทรsetBackground()ในButtonการตั้งค่าพื้นหลังของปุ่ม

ข้อความใด ๆ จะปรากฏขึ้นเหนือพื้นหลัง

หากคุณกำลังมองหาสิ่งที่คล้ายกันใน xml มี: android:backgroundแอตทริบิวต์ซึ่งทำงานในลักษณะเดียวกัน


49
หากคุณไปเส้นทางนี้คุณไม่ต้องการเพียงแค่ใช้ drawable แบบง่ายๆสำหรับพื้นหลัง ใช้ StateListDrawable (โดยทั่วไปผ่านไฟล์ <selector> XML ใน res / drawable /) เพื่อให้คุณสามารถกำหนดพื้นหลังสำหรับสถานะต่างๆ (ปกติ, กด, เน้น, ปิดการใช้งาน ฯลฯ )
CommonsWare

เห็นด้วยกับคุณมองหาคำถามนี้และคำตอบของฉัน: stackoverflow.com/questions/1533038/ …
m_vitaly

1
โง่แค่ไหน ฉันจะพลาดสิ่งนั้นในเอกสารประกอบได้อย่างไร ขอบคุณสำหรับคำตอบที่รวดเร็วและคำแนะนำด้วย <selector> นั่นเป็นสิ่งที่ฉันต้องการนำไปใช้ในอนาคต
znq

3
ไม่สามารถใช้งานได้กับเวอร์ชัน ICS 4.0+ ภาพยืดออก ฉันใช้ TextView กับพื้นหลัง
Meh

612

สำหรับผู้ใช้ที่ต้องการเพียงแค่ใส่พื้นหลังไอคอนภาพและข้อความในหนึ่ง Buttonจากไฟล์ที่แตกต่างกันตั้งอยู่บนButtonพื้นหลัง drawableTop / ล่าง / rigth / ซ้ายและ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>

สำหรับการจัดเรียงที่ซับซ้อนยิ่งขึ้นคุณสามารถใช้RelativeLayout(หรือเค้าโครงอื่น ๆ ) และทำให้คลิกได้

บทช่วยสอน: บทช่วยสอนที่ยอดเยี่ยมที่ครอบคลุมทั้งสองกรณี: http://izvornikod.com/Blog/tabid/82/EntryId/8/Creating-Android-button-with-image-and-text-using-relative-layout.aspx


70
การทำเช่นนี้ใช้โปรแกรมb.setCompoundDrawablesWithIntrinsicBound(null,R.drawable.home_icon_test,null,null)แทนandroid:drawableTopและแทนb.setPadding(0,32,0,0) android:paddingTop
Alex Jasmin

3
การใช้เลย์เอาต์เป็นปุ่มเป็นวิธีการที่ค่อนข้างยืดหยุ่น
sstn

2
เพียงแทนที่ null ด้วย 0 หากคุณใช้รหัสทรัพยากรสำหรับ drawables ของคุณ
Ran

1
ฉันจะปรับขนาดภาพ backgournd ให้พอดีกับปุ่มได้อย่างไร
แอลตัน

@Stallman มีโซลูชัน xml และใช้รหัสเป็นฐานสำหรับการปรับขนาด: stackoverflow.com/questions/8223936/…
OneWorld

346

มีทางออกที่ดีมากสำหรับปัญหานี้คือ

เพียงใช้เวลาปกติButtonและใช้drawableLeftและgravityคุณสมบัติ

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

วิธีนี้คุณจะได้รับปุ่มซึ่งแสดงไอคอนในด้านซ้ายของปุ่มและข้อความที่เว็บไซต์ด้านขวาของไอคอนที่เป็นแนวตั้งศูนย์กลาง


2
ปัญหาเกิดขึ้นกับการแก้ไขนี้หากคุณเลือกที่จะมีสีพื้นหลังบนปุ่ม (ซึ่งมีแนวโน้มในกรณีนี้) จากนั้นจะไม่มีการตอบสนองเชิงกราฟิกสำหรับการคลิกหรือการเลือก คุณสามารถเขียนตัวเลือกเพื่อจัดการสิ่งนี้ แต่จากนั้นคุณจะไม่ได้สีเริ่มต้นของโทรศัพท์
Vanja

9
เพียงแค่ต้องการเพิ่มว่าคุณสมบัติการเติมเต็มแบบ Drawableนั้นมีประโยชน์มากหากใช้วิธีนี้
Nikola Malešević

5
มีวิธีการตั้งค่าความสูง & ความกว้างสำหรับไอคอน drawable ใน xml หรือไม่?
penguru

18
นี่เป็นทางออกที่ยอดเยี่ยมและได้รับการรับรองอย่างเป็นทางการบนไซต์นักพัฒนาซอฟต์แวร์ Android: developer.android.com/guide/topics/ui/controls/button.html
twaddington

3
หากปุ่มมีขนาดใหญ่และข้อความมีความยาวมากกว่าที่ดูน่าเกลียด: ไอคอนที่ด้านซ้ายสุดและข้อความอยู่ตรงกลาง

67

ป้อนคำอธิบายรูปภาพที่นี่

     <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
ทางออกที่ง่ายและผิด สำหรับการจัดตำแหน่งด้านซ้ายเท่านั้น
CoolMind

2
@ CoolMind ฉันอธิบายเฉพาะภาพด้านบนฉันได้แนบมา .. หากคุณต้องการจัดชิดขวาใช้ drawableRight
Dhina k

ฉันไม่ได้คิดที่จะทำสิ่งนี้จนกว่าฉันจะอ่านคำตอบนี้ มันใช้งานได้เหมือนมีเสน่ห์!
sud007

58

เพียงใช้ LinearLayout และแกล้งทำเป็นว่าButton- การตั้งค่าbackgroundและคลิกได้เป็นกุญแจสำคัญ:

<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
วิธีเพิ่มเอฟเฟกต์คลิก
ส่ง

3
คำตอบที่ดีที่สุดด้วยวิธีนี้คุณสามารถจัดการรูปลักษณ์และความรู้สึกได้ 100% และคุณไม่จำเป็นต้องติดไอคอนไว้ที่ขอบ
Climbatize

ตรงandroid:onClickไปตรงมาเพิ่มในมุมมองของคุณ
Giora Guttsait

43

เพียงแค่แทนที่

android:background="@drawable/icon"

กับ

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

izz เป็นเคล็ดลับที่ดีงาม .. ;)


21

ฉันใช้แนวทางที่แตกต่างจากที่ระบุไว้ที่นี่และมันใช้งานได้ดีจริงๆดังนั้นฉันจึงต้องการแบ่งปัน

ฉันใช้สไตล์เพื่อสร้างปุ่มที่กำหนดเองพร้อมรูปภาพทางด้านซ้ายและข้อความที่กึ่งกลางขวา เพียงทำตาม 4 "ขั้นตอนง่าย ๆ " ด้านล่าง:

I. สร้าง 9 แพตช์ของคุณโดยใช้ไฟล์ PNG ที่แตกต่างกันอย่างน้อย 3 ไฟล์และเครื่องมือที่คุณมีอยู่ที่: /YOUR_OWN_PATH/android-sdk-mac_x86/tools/./draw9patch หลังจากนี้คุณควรจะมี:

button_normal.9.png, button_focused.9.png และ button_pressed.9.png

จากนั้นดาวน์โหลดหรือสร้างไอคอน PNG 24x24

ic_your_icon.png

บันทึกทั้งหมดใน drawable / folder ในโครงการ Android ของคุณ

ครั้งที่สอง สร้างไฟล์ XML ชื่อ button_selector.xml ในโครงการของคุณภายใต้ drawable / folder รัฐควรเป็นเช่นนี้:

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

สาม. ไปที่ค่า / โฟลเดอร์และเปิดหรือสร้างไฟล์ styles.xml และสร้างรหัส 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 เป็น "ลูกสไตล์" เพราะมันจะขยาย ButtonNormalText ("สไตล์แม่")

โปรดทราบว่าการเปลี่ยน drawableLeft ในลักษณะ ButtonNormalTextWithIcon เพื่อ drawableRight, drawableTop หรือ drawableBottom คุณสามารถวางไอคอนในตำแหน่งอื่น ๆ ที่เกี่ยวข้องกับข้อความ

IV ไปที่เลย์เอาต์ / โฟลเดอร์ที่คุณมี XML สำหรับ UI และไปที่ปุ่มที่คุณต้องการใช้สไตล์และทำให้มันเป็นดังนี้:

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

และ ... voilà! คุณมีปุ่มพร้อมภาพทางด้านซ้าย

สำหรับฉันนี่เป็นวิธีที่ดีกว่าที่จะทำ! เพราะทำอย่างนี้คุณสามารถจัดการขนาดตัวอักษรของปุ่มแยกจากไอคอนที่คุณต้องการแสดงและใช้พื้นหลังเดียวกัน drawable สำหรับปุ่มต่าง ๆ ที่มีไอคอนต่าง ๆ ที่เกี่ยวข้องกับแนวทาง UI Android โดยใช้สไตล์

คุณยังสามารถสร้างชุดรูปแบบสำหรับแอพของคุณและเพิ่ม "สไตล์ของผู้ปกครอง" เพื่อให้ปุ่มทั้งหมดมีลักษณะเหมือนกันและใช้ "สไตล์ของเด็ก" กับไอคอนเฉพาะที่คุณต้องการ


การทำงานที่ดี. ฉันใช้วิธีมุมมอง FrameLayout กับ ImageView และ TextView ภายใน แต่วิธีนี้ดีกว่า
pilcrowpipe

วิธีการที่ยอดเยี่ยม facebook SDK (รุ่น 3) ใช้วิธีการเดียวกันกับปุ่มลงชื่อเข้าใช้
คนอยู่ที่ไหนสักแห่ง

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

คุณสามารถใช้drawableTop(เช่นdrawableLeftฯลฯ ) สำหรับรูปภาพและตั้งค่าข้อความด้านล่างรูปภาพโดยการเพิ่ม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" />

11

การปรับปรุงที่สำคัญ

อย่าใช้ปกติandroid:drawableLeftฯลฯ ... กับภาพวาดเวกเตอร์อื่นมันจะผิดพลาดในที่ต่ำกว่ารุ่น API (ฉันต้องเผชิญกับมันในแอพถ่ายทอดสด)

สำหรับเวกเตอร์ที่วาดได้

หากคุณใช้การวาดแบบเวกเตอร์คุณจะต้อง

  • คุณได้อพยพไป AndroidX? ถ้าไม่ใช่คุณต้องย้ายไปที่ AndroidX ก่อน มันง่ายมากดูว่า androidx คืออะไรและจะย้ายอย่างไร
  • มันได้รับการปล่อยตัวในรุ่น1.1.0-alpha01ดังนั้นรุ่น AppCompat 1.1.0-alpha01ควรมีอย่างน้อย รุ่นล่าสุดในปัจจุบันจะ1.1.0-alpha02ใช้รุ่นล่าสุดสำหรับความน่าเชื่อถือที่ดีกว่าดูบันทึกประจำรุ่น - การเชื่อมโยง

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

  • ใช้AppCompatTextView/ AppCompatButton/AppCompatEditText

  • การใช้งานapp:drawableLeftCompat, app:drawableTopCompat, app:drawableRightCompat, app:drawableBottomCompat, app:drawableStartCompatและapp:drawableEndCompat

สำหรับ drawable ปกติ

ถ้าคุณไม่จำเป็นต้องวาดเวกเตอร์คุณก็ทำได้

  • การใช้งานandroid:drawableLeft, android:drawableRight, android:drawableBottom,android:drawableTop
  • คุณสามารถใช้เป็นประจำอย่างใดอย่างหนึ่งTextView, ButtonและEditTextหรือAppCompatชั้นเรียน

คุณสามารถบรรลุผลลัพธ์เช่นด้านล่าง -

เอาท์พุต


ฉันใช้xmlns:app="http://schemas.android.com/apk/res-auto"เนมสเปซและไม่เห็นสิ่งที่เข้ากันได้กับแอป
Dale

1
@ ขายเนมสเปซของคุณถูกต้องฉันได้อัปเดตคำตอบแล้วดูFor vector drawableจุดอีกครั้ง
Khemraj

@Khemraj วิธีที่คุณจัดกึ่งกลางทั้ง drawable และข้อความในมุมมองเดียว (ทั้ง TextView หรือปุ่มหรืออย่างอื่น) ตามที่ปรากฏในภาพที่คุณแนบ?
Ambar Jain

7

อาจเป็นไปได้ว่าโซลูชันของฉันจะเหมาะกับผู้ใช้จำนวนมากฉันหวังว่าจะเป็นเช่นนั้น

สิ่งที่ฉันแนะนำคือทำให้ TextView มีสไตล์ของคุณ มันทำงานได้อย่างสมบูรณ์แบบสำหรับฉันและมีคุณสมบัติทั้งหมดเช่นปุ่ม

ก่อนอื่นให้ทำลักษณะปุ่มซึ่งคุณสามารถใช้ได้ทุกที่ ... ฉันกำลังสร้าง 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>

ประการที่สองให้สร้างปุ่มมุมมองข้อความ

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

และนี่คือผลลัพธ์ จากนั้นกำหนดสไตล์ปุ่มที่กำหนดเองของคุณด้วยสีหรือคุณสมบัติและระยะขอบ โชคดี

ป้อนคำอธิบายรูปภาพที่นี่


แม้ว่าฉันยังไม่ได้ทดสอบโค้ดของคุณในขณะที่วิธีการดูเหมือนจะถูกต้อง แต่ฉันไม่เข้าใจสาเหตุของการวางเมาส์บนแอปมือถือ
Mohammed Akhtar Zuberi

ฉันสร้างเอฟเฟ็กต์โฮเวอร์สำหรับแอพของฉันและในระหว่างการสร้างแอพนั้น แต่มันก็ขึ้นอยู่กับคุณ :) คุณสามารถลบเอฟเฟ็กต์โฮเวอร์หากไม่จำเป็น
Jevgenij Kononov

ฉันโหวตคำตอบของคุณเพราะมันเป็นวิธีการที่ดีมาก จุดเดียวของฉันอยู่บนมือถืออินเตอร์เฟสคุณจะโฮเวอร์ได้อย่างไร?
Mohammed Akhtar Zuberi

โอ้ ... ฉันเห็นแล้วตอนนี้ .. : D อ๋อคุณพูดถูกแล้ว มันเป็นไปไม่ได้. ลักษณะพิเศษแบบโฮเวอร์นั้นส่วนใหญ่ใช้สำหรับการกดแบบพิเศษ ชื่อที่ไม่ถูกต้องสำหรับคลาส xml
Jevgenij Kononov


5

รหัสนี้เหมาะกับฉันอย่างสมบูรณ์

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

ฉันลองใช้รหัสของคุณแล้วมันใช้งานได้ แต่ปัญหาหลักของรหัสของคุณถ้าคุณมีชุดปุ่มโดยมีขนาดตัวอักษรแตกต่างกันในแต่ละปุ่ม รูปแบบของคุณจะถูกเปลี่ยน ดังนั้นตำแหน่งภาพแต่ละปุ่มจะอยู่ในตำแหน่งที่แตกต่างกัน ในขณะที่ควรตรงกลาง นี่คือสิ่งที่เกิดขึ้นกับปุ่ม
Jevgenij Kononov

0

คุณสามารถใช้สิ่งนี้:

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

ในที่ฉันได้ใส่ภาพเป็นbackgroundและยังเพิ่มข้อความ .. !


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

หรือคุณสามารถเขียนโปรแกรม:

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

นี่ไม่ใช่คำตอบที่ถูกต้องเนื่องจากมุมมองรูปภาพไม่สนับสนุนข้อความ
Muhammed Fasil
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.