안드로이드 : 버튼 또는 이미지 버튼에 텍스트 및 이미지 결합


540

버튼에 이미지 (배경으로)를 가지고 런타임에 발생하는 상황에 따라 이미지 위 / 위에 일부 텍스트를 동적으로 추가하려고합니다.

내가 사용 ImageButton하면 텍스트를 추가 할 수조차 없습니다. 내가 사용 Button하면 텍스트를 추가 할 수 있지만 여기에android:drawableBottom 정의 된 것과 유사한 XML 속성을 가진 이미지 만 정의 할 수 있습니다 .

그러나 이러한 속성은 텍스트와 이미지를 x 및 y 차원으로 만 결합하므로 텍스트 주위에 이미지를 그릴 수 있지만 텍스트 아래 / 아래에는 표시 할 수 없습니다 (z- 축은 디스플레이에서 나오는 것으로 정의 됨).

이 작업을 수행하는 방법에 대한 제안 사항이 있습니까? 한 가지 아이디어는 -method를 확장 Button하거나 ImageButton재정의하는 draw()것입니다. 그러나 내 현재의 지식 수준으로 실제로이 작업을 수행하는 방법을 알지 못합니다 (2D 렌더링). 더 많은 경험을 가진 사람이 해결책이나 적어도 시작해야 할 지침을 알고 있습니까?


9 패치, 스마트 솔루션 사용
Kaveh Garshasp

답변:


205

당신은 호출 할 수 있습니다 setBackground()A의 Button버튼의 배경을 설정할 수 있습니다.

모든 텍스트가 배경 위에 나타납니다.

xml에서 비슷한 것을 찾고 있다면 : android:background동일한 방식으로 작동하는 attribute가 있습니다.


49
이 경로를 사용하면 배경에 간단한 드로어 블을 사용하고 싶지 않습니다. StateListDrawable (보통 res / drawable /의 <selector> XML 파일을 통해)을 사용하면 다양한 상태 (일반, 압축, 포커스, 비활성화 등)의 배경을 정의 할 수 있습니다.
CommonsWare

당신과 동의,이 질문과 내 대답을
찾으십시오

1
어리 석다 문서에서 어떻게 그것을 놓칠 수 있었습니까? 빠른 답변과 <selector>의 힌트에 감사드립니다. 그것은 미래에 분명히 구현하고 싶은 것입니다.
znq

3
ICS 4.0+ 버전에서는 제대로 작동하지 않으며 이미지가 늘어납니다. 배경이있는 TextView를 사용하고있었습니다.
meh

612

배경, 아이콘 이미지 및 텍스트 Button 를 다른 파일 에서 하나만Button 넣으려는 사용자의 경우 : 배경, drawableTop / Bottom / Rigth / Left 및 패딩 속성에 설정하십시오.

<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:drawableTopb.setPadding(0,32,0,0)대신을 android:paddingTop.
Alex Jasmin 2:30에

3
레이아웃을 버튼으로 사용하는 것은 실제로 매우 유연한 접근 방식입니다.
sstn

2
드로어 블에 리소스 ID를 사용하는 경우 null을 0으로 바꾸십시오.
Ran

1
backgournd 이미지의 크기를 버튼에 맞게 조정하려면 어떻게해야합니까?
Alston

@Stallman 확장을위한 XML 기반 및 코드 기반 솔루션이 있습니다 : stackoverflow.com/questions/8223936/…
OneWorld

346

이 문제에 대한 훨씬 더 나은 해결책이 있습니다.

그냥 정상을 취하고 및 속성을 Button사용하십시오 .drawableLeftgravity

<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
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
클릭 효과를 추가하는 방법?
frankish

3
가장 좋은 대답은이 방법으로 모양과 느낌의 100 %를 관리하며 아이콘을 테두리에 붙일 필요가 없습니다.
Climbatize

솔직한, android:onClick당신의 전망에 추가
Giora Guttsait

43

그냥 교체

android:background="@drawable/icon"

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

이건 꽤 좋은 트릭입니다 ..;)


21

나는 여기에 언급 된 것과 다른 접근법을 취했으며 실제로 잘 작동하고 있으므로 공유하고 싶었습니다.

스타일을 사용하여 왼쪽에 이미지가 있고 가운데 오른쪽에 텍스트가있는 사용자 정의 버튼을 만듭니다. 아래의 4 가지 "쉬운 단계"를 따르십시오.

I. /YOUR_OWN_PATH/android-sdk-mac_x86/tools/./draw9patch에있는 최소 3 개의 다른 PNG 파일과 도구를 사용하여 9 개의 패치를 만듭니다. 이 후 당신은해야합니다 :

button_normal.9.png, button_focused.9.png 및 button_pressed.9.png

그런 다음 24x24 PNG 아이콘을 다운로드하거나 만듭니다.

ic_your_icon.png

Android 프로젝트의 drawable / 폴더에 모두 저장하십시오.

II. 프로젝트에서 drawable / 폴더 아래 button_selector.xml이라는 XML 파일을 만듭니다. 상태는 다음과 같아야합니다.

<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. values ​​/ 폴더로 이동하여 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 ( "부모 스타일")를 확장하므로 "자식"입니다.

ButtonNormalTextWithIcon 스타일에서 drawableLeft를 drawableRight, drawableTop 또는 drawableBottom으로 변경하면 아이콘을 텍스트와 관련하여 다른 위치에 배치 할 수 있습니다.

IV. UI 용 XML이있는 레이아웃 / 폴더로 이동하고 스타일을 적용하려는 버튼으로 이동하여 다음과 같이 만듭니다.

<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à! 왼쪽에 이미지가있는 버튼이 있습니다.

저에게는 이것이 더 좋은 방법입니다! 이 방법을 사용하면 표시하려는 아이콘과 별도로 버튼의 텍스트 크기를 관리하고 스타일을 사용하는 Android UI 지침을 존중하는 다른 아이콘이있는 여러 버튼에 대해 동일한 배경 드로어 블을 사용할 수 있습니다.

또한 앱의 테마를 생성하고 "부모 스타일"을 추가하여 모든 버튼이 동일하게 보이도록하고 필요한 경우에만 아이콘으로 "자식"을 적용 할 수 있습니다.


잘 했어. ImageView 및 TextView가있는 FrameLayout보기 접근 방식을 사용했지만이 방법이 더 좋습니다.
pilcrowpipe

멋진 접근법. 페이스 북 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벡터 드로어 블과 함께 normal 등을 사용하지 마십시오. 그렇지 않으면 더 낮은 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:drawableStartCompatapp:drawableEndCompat

일반 드로어 블

벡터 드로어 블이 필요하지 않은 경우

  • 사용 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 첨부 한 이미지에 표시된 것처럼 단일 뷰 (TextView 또는 Button 또는 기타)에서 드로어 블과 텍스트를 가운데에 맞추는 방법은 무엇입니까?
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.