435

Is it possible to set the margin or padding for the image which we added with the android:drawableLeft?

Rahul Tiwari
  • 6,851
  • 3
  • 49
  • 78
androidNewbies
  • 4,351
  • 2
  • 16
  • 3

19 Answers19

518

As cephus mentioned android:drawablePadding will only force padding between the text and the drawable if the button is small enough.

When laying out larger buttons you can use android:drawablePadding in conjunction with android:paddingLeft and android:paddingRight to force the text and drawable inward towards the center of the button. By adjusting the left and right padding separately you can make very detailed adjustments to the layout.

Here's an example button that uses padding to push the text and icon closer together than they would be by default:

<Button android:text="@string/button_label" 
    android:id="@+id/buttonId"
    android:layout_width="160dip"
    android:layout_height="60dip"
    android:layout_gravity="center"
    android:textSize="13dip"
    android:drawableLeft="@drawable/button_icon"
    android:drawablePadding="2dip"
    android:paddingLeft="30dip"
    android:paddingRight="26dip"
    android:singleLine="true"
    android:gravity="center" />  
Jordan
  • 6,083
  • 3
  • 23
  • 30
  • 28
    android:paddingLeft="30dip" android:paddingRight="26dip" are key here! – IgorGanapolsky Nov 21 '11 at 18:05
  • 7
    this is not related to the question, but android:gravity="center" will keep the text aligned with center of the drawable! – cwhsu Mar 02 '14 at 01:32
  • 2
    What if we have drawables both at left and right, and only have to adjust right drawable?? – nmxprime Jun 24 '14 at 13:27
  • 1
    I only use: android:paddingLeft, and it changes position of image. android:drawablePadding is used for space between image and text. – Brave Oct 17 '14 at 08:38
  • 1
    The issue of this code is it causes `passwordToggleDrawable` left padding gap become bigger since it can't specific target to left drawable only. – 林果皞 Jan 10 '19 at 18:51
210

TextView has an android:drawablePadding property which should do the trick:

android:drawablePadding

The padding between the drawables and the text.

Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp". Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size), in (inches), mm (millimeters).

This may also be a reference to a resource (in the form "@[package:]type:name") or theme attribute (in the form "?[package:][type:]name") containing a value of this type.

This corresponds to the global attribute resource symbol drawablePadding.

Cheryl Simon
  • 46,552
  • 15
  • 93
  • 82
69

android:drawablePadding will only create a padding gap between the text and the drawable if the button is small enough to squish the 2 together. If your button is wider than the combined width (for drawableLeft/drawableRight) or height (for drawableTop/drawableBottom) then drawablePadding doesn't do anything.

I'm struggling with this right now as well. My buttons are quite wide, and the icon is hanging on the left edge of the button and the text is centered in the middle. My only way to get around this for now has been to bake in a margin on the drawable by adding blank pixels to the left edge of the canvas with photoshop. Not ideal, and not really recommended either. But thats my stop-gap solution for now, short of rebuilding TextView/Button.

Ragunath Jawahar
  • 19,513
  • 22
  • 110
  • 155
cephus
  • 2,027
  • 1
  • 13
  • 10
50

Yes. use drawablePadding as follows,

<TextView
        android:id="@+id/tvHeader"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Settings and Contents"
        android:drawableLeft="@drawable/icon_success"
        android:drawablePadding="10dp" />
Parinda Rajapaksha
  • 2,963
  • 1
  • 36
  • 40
43

Make your drawable resources.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true">
        <inset android:drawable="@drawable/small_m" android:insetLeft="10dp" android:insetTop="10dp" />
    </item>
    <item>
        <inset android:drawable="@drawable/small_p" android:insetLeft="10dp" android:insetTop="10dp" />
    </item>
</selector>
The Finest Artist
  • 3,150
  • 29
  • 34
  • 2
    @ The Finest Artist I have use inset in drawable and it's working fine for newer version devices. I mean its not working in SDK 16, 17 but working in SDK 23. Is there any idea? – Bhavin Chauhan Mar 11 '16 at 12:09
  • 2
    http://developer.android.com/reference/android/graphics/drawable/InsetDrawable.html its from API 1 – Bhavin Chauhan Mar 11 '16 at 12:10
  • Nice answer and upvote for this. You just help me solve a problem that confused me for a long time. – Anthonyeef Jul 07 '16 at 02:48
39

android:drawablePadding is the easiest way to give padding to drawable icon but You can not give specific one side padding like paddingRight or paddingLeft of drawable icon.To achieve that you have to dig into it. And If you apply paddingLeft or paddingRight to Edittext then it will place padding to entire Edittext along with drawable icon.

Bhargav Thanki
  • 4,924
  • 2
  • 37
  • 43
30

According to @Bhargav Thanki:

android:drawablePadding is the easiest way to give padding to drawable icon but You can not give specific one side padding like paddingRight or paddingLeft of drawable icon.To achieve that you have to dig into it. And If you apply paddingLeft or paddingRight to EditText then it will place padding to entire EditText along with drawable icon.

Example:

    <TextView 
        android:layout_width="match_parent"
        android:padding="5dp"
        android:id="@+id/date"
        android:gravity="center|start"
        android:drawableEnd="@drawable/ic_calendar"
        android:background="@drawable/edit_background"
        android:hint="Not Selected"
        android:drawablePadding="10dp"
        android:paddingStart="10dp"
        android:paddingEnd="10dp"
        android:textColor="@color/black"
        android:layout_height="wrap_content"/>
mrtnrst
  • 41
  • 6
VikasSharmalp
  • 492
  • 1
  • 6
  • 16
  • 1
    it's padding between icon and text, but what about padding before edittext start and drawable start? – user924 May 07 '21 at 09:35
15

define a shape for your edittext and give it a padding For Example

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
    <padding
        android:left="5dp"
        android:right="5dp"
    />
    <solid android:color="#F6F6F6" />
    <stroke
        android:width="1px"
        android:color="#C3C3C3" />

    <corners
        android:bottomLeftRadius="1dp"
        android:bottomRightRadius="1dp"
        android:topLeftRadius="1dp"
        android:topRightRadius="1dp" />
</shape>

The padding defined in this shape will help in give padding to drawableleft or right ---------------------- Apply this shape on EditView

 <EditText
            android:id="@+id/example"
            android:layout_width="fill_parent"
            android:layout_height="36dp"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:background="@drawable/shape2"
            android:drawableLeft="@drawable/icon1"
            android:drawablePadding="@dimen/txtDrwblPadding"
            android:ems="10"
         />

using that defined shape as background will give your EditText some style plus margin to drawableLeft.

Pratik Butani
  • 60,504
  • 58
  • 273
  • 437
Umesh N
  • 211
  • 4
  • 5
14
<TextView
    android:layout_width="wrap_content"
    android:layout_height="32dp"
    android:background="@drawable/a"
    android:drawableLeft="@drawable/concern_black"
    android:gravity="center"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:drawablePadding="10dp"
    android:text="text"/>

note: layout_width needs to be wrap_content and use paddingLeft paddingRight drawablePadding to control gap. If you specify layout_width value is will has gap between icon and text, I think once give the layout_width a specify value, the padding will measure.

Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
王良海
  • 201
  • 3
  • 5
12

I'll throw my answer into the ring as well. If you want to do this programmatically you can do the following.

final Drawable drawable = ContextCompat.getDrawable(getContext(), R.drawable.somedrawable);
final boolean isLTR = ViewCompat.LAYOUT_DIRECTION_LTR == ViewCompat.getLayoutDirection(this);
final int iconInsetPadding = getResources().getDimensionPixelSize(R.dimen.icon_padding);

final Drawable insetDrawable = new InsetDrawable(drawable, isLTR ? 0 : iconInsetPadding, 0, isLTR ? iconInsetPadding : 0, 0);

This will add the padding to the end of the drawable where end will mean left/right depending if phone is in LTR or RTL.

Daniel Ochoa
  • 1,792
  • 1
  • 16
  • 22
11

Another easy solution can be achieved by inset layerlist

layered_drawable

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item>
        <inset
            android:insetRight="30dp"
            android:drawable="@drawable/ic_air_date">
        </inset>
    </item>
</layer-list>

Button in XML

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:drawableLeft="@drawable/layered_drawable"
    android:text="something" />
sadat
  • 4,004
  • 2
  • 29
  • 49
8

Instead of Button use LinearLayout with ImageView and TextView inside. In child items like ImageView and TextView use android:duplicateParentState="true".

Milad Faridnia
  • 9,113
  • 13
  • 65
  • 78
Alexey Zakharov
  • 24,694
  • 42
  • 126
  • 197
  • You will actually need a FrameLayout and a Button (and the ImageView/TextView inside their own LinearLayout) to reproduce the Button UI and transfer the onclicklistener() to the button part – 3c71 Mar 21 '14 at 19:14
  • 4
    Why using additional layout if you already have drawablePadding in TextView. – Parinda Rajapaksha Aug 10 '17 at 10:37
5

You can use a padding for the button and you can play with drawablePadding

 <Button
    style="@style/botonesMenu"
    android:padding="15dp"
    android:drawablePadding="-15dp"
    android:text="@string/actualizarBD"
    android:textAlignment="gravity"
    android:gravity="center"
    android:layout_row="1"
    android:layout_column="0"
    android:drawableTop="@drawable/actualizar"
    android:id="@+id/btnActualizar"
    android:onClick="actualizarBD" />

you can use a specific padding depends where put your drawable, with android:paddingLeft="10dp" or android:paddingBottom="10dp" or android:paddingRight="10dp" or android:paddingTop="10dp"

Carolina
  • 141
  • 2
  • 7
5

You should consider using layer-list

Create a drawable file like this, name it as ic_calendar.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
    <shape android:shape="rectangle">
        <solid android:color="@android:color/transparent"/>
    </shape>
</item>
<item android:right="10dp">
    <bitmap android:gravity="center_vertical|left"
        android:src="@drawable/ic_calendar_16dp"
        android:tint="@color/red"
        />
</item>
</layer-list>

Under layout file,

<TextView
         android:id="@+id/tvDate"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:drawableLeft="@drawable/ic_calendar"
         android:textColor="@color/colorGrey"
         android:textSize="14sp" 
    />
RayChongJH
  • 401
  • 1
  • 5
  • 6
3

You can use android:drawableLeft="@drawable/your_icon" to set the drawable to be shown on the left side. In order to set a padding for the drawable you should use the android:paddingLeft or android:paddingRight to set the left/right padding respectively.

android:paddingRight="10dp"
android:paddingLeft="20dp"
android:drawableRight="@drawable/ic_app_manager"
AouledIssa
  • 2,528
  • 2
  • 22
  • 39
3

just remake from:

<?xml version="1.0" encoding="utf-8"?>
<shape
        xmlns:android="http://schemas.android.com/apk/res/android">

    <corners android:radius="40dp"/>

    <solid android:color="@android:color/white"/>

</shape>

to

<layer-list
        xmlns:android="http://schemas.android.com/apk/res/android">
    <item
            android:right="@dimen/_2dp"
            android:left="@dimen/_2dp"
            android:bottom="@dimen/_2dp"
            android:top="@dimen/_2dp"
            >
        <shape
                xmlns:android="http://schemas.android.com/apk/res/android">

            <corners android:radius="40dp"/>

            <solid android:color="@android:color/white"/>

        </shape>
    </item>

</layer-list>
nicolas asinovich
  • 3,201
  • 3
  • 27
  • 37
1

If the size of drawable resouce is fixed, you can do like this:

<Button
    android:background="@drawable/rounded_button_green"
    style="?android:attr/selectableItemBackground"
    android:layout_height="wrap_content"
    app:layout_widthPercent="70%"
    android:drawableRight="@drawable/ic_clear_black_24dp"
    android:paddingRight="10dp"
    android:paddingLeft="34dp"
    tools:text="example" />

The key here is that:

    android:drawableRight="@drawable/ic_clear_black_24dp"
    android:paddingRight="10dp"
    android:paddingLeft="34dp"

That is, the size of drawable resource plus paddingRight is the paddingLeft.

You can see the result in this example

1
textView.setCompoundDrawablesWithIntrinsicBounds(AppCompatResources.getDrawable(this,drawable),null,null,null);

addressTitleView.setCompoundDrawablePadding();
dkackman
  • 15,179
  • 13
  • 69
  • 123
  • While this code snippet may solve the question, [including an explanation](http://meta.stackexchange.com/questions/114762/explaining-entirely-‌​code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – Rosário Pereira Fernandes Mar 03 '18 at 22:15
  • This only works for text view not e.g. button which also allows to set start/end drwables – User Jun 12 '18 at 14:33
-7

Tries to use negative padding

Like:

android:paddingLeft="-8dp"