Android: kết hợp văn bản & hình ảnh trên Nút hoặc ImageButton


540

Tôi đang cố gắng để có một hình ảnh (làm nền) trên một nút và thêm động, tùy thuộc vào những gì xảy ra trong thời gian chạy, một số văn bản ở trên / trên hình ảnh.

Nếu tôi sử dụng, ImageButtontôi thậm chí không có khả năng thêm văn bản. Nếu tôi sử dụng, Buttontôi có thể thêm văn bản nhưng chỉ xác định một hình ảnh có android:drawableBottomcác thuộc tính XML tương tự như được định nghĩa ở đây .

Tuy nhiên, các thuộc tính này chỉ kết hợp văn bản & hình ảnh theo kích thước x và y, nghĩa là tôi có thể vẽ một hình ảnh xung quanh văn bản của mình, nhưng không nằm dưới / bên dưới văn bản của tôi (với trục z được xác định là xuất hiện trên màn hình).

Có bất cứ đề nghị nào cho việc làm như thế này hả? Một ý tưởng sẽ là mở rộng Buttonhoặc ImageButtonghi đè lên draw()-method. Nhưng với trình độ kiến ​​thức hiện tại của tôi, tôi thực sự không biết làm thế nào để thực hiện điều này (kết xuất 2D). Có lẽ ai đó có nhiều kinh nghiệm biết một giải pháp hoặc ít nhất là một số gợi ý để bắt đầu?


sử dụng 9Patch, giải pháp thông minh
Kaveh Garshasp

hi @Charu ක xin vui lòng kiểm tra điều này nếu bạn có thể stackoverflow.com/questions/42968587/...
Mohamed Rihan

Câu trả lời:


205

Bạn có thể gọi setBackground()vào một Buttonđể đặt nền của nút.

Bất kỳ văn bản sẽ xuất hiện trên nền.

Nếu bạn đang tìm kiếm một cái gì đó tương tự trong xml, có: android:backgroundthuộc tính hoạt động theo cùng một cách.


49
Nếu bạn đi theo con đường này, bạn không muốn chỉ sử dụng một drawable đơn giản cho nền. Sử dụng tệp StateListDrawable (thường thông qua tệp <selector> XML trong res / drawable /), do đó bạn có thể xác định nền cho các trạng thái khác nhau (bình thường, nhấn, tập trung, tắt, v.v.).
CommonsWare

Đồng ý với bạn, hãy tìm câu hỏi này và câu trả lời của tôi: stackoverflow.com/questions/1533038/iêu
m_vitaly

1
Thật ngu ngốc. Làm thế nào tôi có thể đã bỏ lỡ điều đó trong tài liệu. Cảm ơn câu trả lời nhanh và cũng là gợi ý với <bộ chọn>. Đó là điều tôi chắc chắn muốn thực hiện trong tương lai.
znq

3
Nó không hoạt động ngay trên các phiên bản ICS 4.0+, hình ảnh trải dài. Tôi đã sử dụng TextView với nền.
meh

612

Đối với người dùng chỉ muốn đặt Nền, Biểu tượng-Hình ảnh và Văn bản vào một trong Button các tệp khác nhau: Đặt trên Buttonnền, các thuộc tính drawableTop / bottom / Rigth / Left và 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>

Để sắp xếp tinh vi hơn, bạn cũng có thể sử dụng RelativeLayout(hoặc bất kỳ bố cục nào khác) và làm cho nó có thể nhấp được.

Hướng dẫn: Hướng dẫn tuyệt vời bao gồm cả hai trường hợp: http://izvornikod.com/Blog/tabid/82/EntryId/8/Creating-Android-button-with-image-and-text-USE-relative-layout.aspx


70
Để làm điều này lập trình sử dụng b.setCompoundDrawablesWithIntrinsicBound(null,R.drawable.home_icon_test,null,null)thay vì android:drawableTopb.setPadding(0,32,0,0)thay vì android:paddingTop.
Alex Jasmin

3
Sử dụng một bố cục như một nút thực sự là một cách tiếp cận khá linh hoạt.
sstn

2
Chỉ cần thay null bằng 0 nếu bạn đang sử dụng id tài nguyên cho các tài khoản của mình
Ran

1
Làm cách nào tôi có thể chia tỷ lệ hình ảnh backgournd cho vừa với nút?
Alston

@Stallman Có một xml-based và giải pháp mã có trụ sở rộng: stackoverflow.com/questions/8223936/...
OneWorld

346

Có một giải pháp tốt hơn cho vấn đề này.

Chỉ cần bình thường Buttonvà sử dụng drawableLeftcác gravitythuộc tính và.

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

Bằng cách này, bạn nhận được một nút hiển thị một biểu tượng ở phía bên trái của nút và văn bản ở vị trí bên phải của biểu tượng được đặt ở giữa .


2
Một vấn đề xảy ra với giải pháp này nếu bạn chọn có màu nền trên nút (có khả năng trong trường hợp này). Sau đó, sẽ không có phản ứng đồ họa để nhấp hoặc lựa chọn. Bạn có thể viết một bộ chọn để xử lý việc này, nhưng sau đó bạn sẽ không nhận được màu mặc định của điện thoại.
Vanja

9
Chỉ muốn thêm rằng thuộc tính đệm Drawable là rất hữu ích nếu giải pháp này được sử dụng.
Nikola Malešević

5
Có cách nào để đặt chiều cao và chiều rộng cho biểu tượng có thể vẽ trong xml không?
chim cánh cụt

18
Đây là một giải pháp tuyệt vời và cũng chính thức được xác nhận trên trang web dành cho nhà phát triển Android: developer.android.com/guide/topics/ui/controls/button.html
twaddington

3
nếu nút lớn và văn bản dài thay đổi, trông giống như xấu xí: biểu tượng ở hầu hết bên trái và văn bản ở đâu đó ở giữa

67

nhập mô tả hình ảnh ở đây

     <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
Một giải pháp đơn giản và sai lầm. Chỉ cho căn lề trái.
CoolMind

2
@ CoolMind Tôi chỉ giải thích cho hình ảnh trên mà tôi đã đính kèm .. nếu bạn muốn căn chỉnh đúng cách sử dụng drawableRight
Dhina k

Tôi thậm chí đã không nghĩ làm điều này cho đến khi tôi đọc câu trả lời này. Công việc này như một cái duyên vậy!
sud007

58

Chỉ cần sử dụng linearLayout và giả vờ đó là Button- cài đặt backgroundcó thể nhấp là chìa khóa:

<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
Làm thế nào để thêm hiệu ứng nhấp chuột?
thắn

3
Câu trả lời hay nhất, theo cách này bạn quản lý 100% giao diện và bạn không phải dán biểu tượng vào đường viền.
Leo lên

thẳng thắn, thêm android:onClickvào quan điểm của bạn
Giora Guttsait

43

chỉ cần thay thế

android:background="@drawable/icon"

với

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

izz một mẹo khá hay ..;)


21

Tôi đã thực hiện một cách tiếp cận khác với những cách đã nêu ở đây, và nó đang hoạt động rất tốt, vì vậy tôi muốn chia sẻ nó.

Tôi đang sử dụng Kiểu để tạo nút tùy chỉnh với hình ảnh ở bên trái và văn bản ở giữa bên phải. Chỉ cần làm theo 4 "bước dễ dàng" dưới đây:

I. Tạo 9 bản vá của bạn bằng cách sử dụng ít nhất 3 tệp PNG khác nhau và công cụ bạn có tại: /YOUR_OWN_PATH/android-sdk-mac_x86/tools/./draw9patch. Sau này, bạn nên có:

button_n normal.9.png, button_f Focused.9.png và button_pressed.9.png

Sau đó tải xuống hoặc tạo biểu tượng 24x24 PNG.

ic_your_icon.png

Lưu tất cả trong thư mục drawable / trên dự án Android của bạn.

II. Tạo một tệp XML có tên là button_selector.xml trong dự án của bạn trong thư mục drawable /. Các tiểu bang nên như thế này:

<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. Chuyển đến các giá trị / thư mục và mở hoặc tạo tệp Styles.xml và tạo mã XML sau:

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

NútN normalTextWithIcon là "kiểu con" bởi vì nó đang mở rộng NútN normalText ("kiểu cha mẹ").

Lưu ý rằng việc thay đổi drawableLeft theo kiểu NútN normalTextWithIcon, thành drawableRight, drawableTop hoặc drawableBottom, bạn có thể đặt biểu tượng ở vị trí khác đối với văn bản.

IV. Chuyển đến bố cục / thư mục nơi bạn có XML cho Giao diện người dùng và đi tới Nút nơi bạn muốn áp dụng kiểu và làm cho nó trông như thế này:

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

Và Voila! Bạn có nút của bạn với một hình ảnh ở phía bên trái.

Đối với tôi, đây là cách tốt hơn để làm điều đó! bởi vì làm theo cách này, bạn có thể quản lý kích thước văn bản của nút riêng biệt với biểu tượng bạn muốn hiển thị và sử dụng cùng một nền có thể vẽ cho một số nút với các biểu tượng khác nhau tôn trọng Nguyên tắc giao diện người dùng Android bằng các kiểu.

Bạn cũng có thể tạo một chủ đề cho Ứng dụng của mình và thêm "kiểu cha mẹ" vào nó để tất cả các nút trông giống nhau và áp dụng "kiểu con" với biểu tượng chỉ khi bạn cần.


Làm tốt lắm. Tôi đã sử dụng cách tiếp cận khung nhìn FrameLayout với ImageView và TextView bên trong, nhưng cách tiếp cận này đẹp hơn.
pilcrowpipe

Cách tiếp cận tuyệt vời. SDK facebook (phiên bản 3) có cách tiếp cận tương tự cho nút đăng nhập
Ai đó ở đâu đó vào

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

Bạn có thể sử dụng drawableTop(cũng drawableLeft, v.v.) cho hình ảnh và đặt văn bản bên dưới hình ảnh bằng cách thêmgravity 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

Cập nhật quan trọng

Không sử dụng bình thường, android:drawableLeftv.v ... với các bản vẽ vector, nếu không nó sẽ bị sập trong các phiên bản API thấp hơn . (Tôi đã đối mặt với nó trong ứng dụng trực tiếp)

Đối với vector có thể vẽ

Nếu bạn đang sử dụng vector drawable, thì bạn phải

  • Bạn đã chuyển sang AndroidX chưa? nếu không bạn phải di chuyển sang AndroidX trước. Nó rất đơn giản, xem androidx là gì và làm thế nào để di chuyển?
  • Nó đã được phát hành trong phiên bản 1.1.0-alpha01, vì vậy ít nhất là phiên bản appcompat 1.1.0-alpha01. Phiên bản mới nhất hiện tại là 1.1.0-alpha02, sử dụng các phiên bản mới nhất để có độ tin cậy tốt hơn, xem ghi chú phát hành - liên kết .

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

  • Sử dụng AppCompatTextView/ AppCompatButton/AppCompatEditText

  • Sử dụng app:drawableLeftCompat, app:drawableTopCompat, app:drawableRightCompat, app:drawableBottomCompat, app:drawableStartCompatapp:drawableEndCompat

Đối với thường xuyên rút

Nếu bạn không cần vector có thể vẽ, thì bạn có thể

  • sử dụng android:drawableLeft, android:drawableRight, android:drawableBottom,android:drawableTop
  • Bạn có thể sử dụng thường xuyên TextView, ButtonEditTexthoặc AppCompatcác lớp học.

Bạn có thể đạt được Kết quả như bên dưới -

đầu ra


Tôi đang sử dụng xmlns:app="http://schemas.android.com/apk/res-auto"không gian tên và không thấy những thứ tương thích với ứng dụng đó.
Dale

1
@Dale không gian tên của bạn là chính xác, tôi đã cập nhật câu trả lời của tôi, xem For vector drawablelại điểm.
Khemraj

@Khemraj Làm thế nào bạn định tâm cả hai có thể vẽ và văn bản trong chế độ xem đơn (có thể là TextView hoặc Nút hoặc một cái gì khác) như được hiển thị trong hình ảnh bạn đính kèm?
Ambar Jain

7

Có lẽ giải pháp của tôi sẽ phù hợp với rất nhiều người dùng, tôi hy vọng vậy.

Những gì tôi đang đề xuất là tạo TextView với phong cách của bạn. Nó hoạt động hoàn hảo với tôi, và có tất cả các tính năng, như một nút.

Trước hết, hãy tạo kiểu nút, mà bạn có thể sử dụng ở mọi nơi ... Tôi đang tạo 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>

Thứ hai, cho phép tạo một nút xem văn bản.

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

Và đây là một kết quả. Sau đó, tạo kiểu cho nút tùy chỉnh của bạn với bất kỳ màu nào hoặc bất kỳ thuộc tính và lề nào khác. Chúc may mắn

nhập mô tả hình ảnh ở đây


Mặc dù tôi chưa kiểm tra mã của bạn vì cách tiếp cận có vẻ đúng, nhưng tôi không hiểu lý do có hiệu ứng di chuột trong ứng dụng di động.
Mohammed Akhtar Zuberi

Tôi đã tạo hiệu ứng di chuột cho ứng dụng của mình và trong quá trình xây dựng ứng dụng đó, tôi cần hiệu ứng di chuột. Nhưng nó là tùy thuộc vào bạn :) Bạn có thể xóa hiệu ứng di chuột nếu không cần thiết.
Jevgenij Kononov

Tôi đã bỏ phiếu cho câu trả lời của bạn vì nó là một cách tiếp cận rất tốt. Điểm duy nhất của tôi là trên giao diện di động, làm thế nào bạn có thể di chuột?
Mohammed Akhtar Zuberi

Ồ ... tôi hiểu rồi ..: D Yeap, bạn nói đúng. Nó là không thể. Hiệu ứng di chuột đó chủ yếu là cho hiệu ứng nhấn. Chỉ tên không chính xác cho lớp xml
Jevgenij Kononov


5

Mã này hoạt động hoàn hảo với tôi

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

Tôi đã thử mã của bạn .. nó hoạt động nhưng vấn đề chính của mã của bạn nếu bạn có bộ nút, với các kích cỡ văn bản khác nhau trong mỗi nút. Bố cục của bạn sẽ được thay đổi. Vì vậy, mỗi vị trí hình ảnh của nút sẽ ở một nơi khác nhau. Trong khi nó phải thẳng ở trung tâm. Đây là những gì xảy ra với nút.
Jevgenij Kononov

0

Bạn có thể sử dụng điều này:

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

trong đó tôi đã đặt một hình ảnh như backgroundvà cũng thêm văn bản ..!


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

Hoặc bạn có thể lập trình:

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

Đây không phải là một câu trả lời đúng vì Chế độ xem hình ảnh không hỗ trợ văn bản
Muhammed Fasil
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.