109

I added some icons on 4 buttons and they look so big next to the button. So how can I resize them? I used drawableLeft on the buttons to add icons.

The drawables are called deal, trophy, puzzle and megaphone. The icons are too big. The content_main.xml file:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/content_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="tr.k12.evrim.evrimnews.MainActivity"
    tools:showIn="@layout/activity_main">




    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/frameLayout"
        android:layout_alignParentTop="true"
        android:layout_alignParentStart="true">


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <Button
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Giriş Yap"
                android:onClick="SignIn"
                android:textStyle="bold"
                style="@style/Widget.AppCompat.Button.Colored"/>




            </LinearLayout>


    </FrameLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="400dp"
        android:layout_below="@id/frameLayout"
        android:orientation="vertical">



    <Button
        android:text="Duyurular"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:layout_below="@+id/frameLayout"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="13dp"
        android:id="@+id/button2"
        android:drawableLeft="@drawable/megaphone" />

    <Button
        android:text="Kadromuz"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:layout_below="@+id/button2"
        android:layout_alignEnd="@+id/button2"
        android:layout_marginTop="13dp"
        android:id="@+id/button3"
        android:drawableLeft="@drawable/puzzle"/>

        <Button
            android:text="Başarılarımız"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:layout_marginTop="12dp"
            android:id="@+id/button5"
            android:drawableLeft="@drawable/trophy"/>


    <Button
        android:text="Ortaklarımız"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:layout_marginTop="12dp"
        android:id="@+id/button4"
        android:drawableLeft="@drawable/deal"/>




    </LinearLayout>

</RelativeLayout>
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Arda Çebi
  • 1,705
  • 4
  • 15
  • 27

10 Answers10

266

Wrap your resource in a drawable that defines your desired size similar to:

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

  <item
      android:drawable="@drawable/icon"
      android:width="@dimen/icon_size"
      android:height="@dimen/icon_size"
      />

</layer-list >

After that, use this drawable in your android:drawableLeft tag

DroidBender
  • 7,762
  • 4
  • 28
  • 37
  • 86
    @MuhammedRefaat Be careful with this solution, the attribute *width* and *height* is only compatible with API 23 or newer, so it doesn't work with Lollipop and under version. – Eduardo E.R. May 18 '17 at 18:44
  • 1
    @EduardoE.R. wow, I didn't know that, glad you told me, thank you – Muhammed Refaat May 21 '17 at 05:20
  • @EduardoE.R. can you guide me how to make compatible attribute width and height with below 23 version , so I can show the icon as same size in lollipop and under version , many many thanks in advance – Amit Verma Mar 03 '18 at 06:44
  • 1
    @AmitVerma this solution is compatible with below 23 version, I mean, it will not crash, but the will not have the same size. I really don't know if there is another better approach. Maybe you can use another layout for this API version and use an Image tag given a button behaviour to it, you know, onclick event, onPress event... sorry if not sound a really good solution. – Eduardo E.R. Mar 04 '18 at 00:11
  • 2
    As a beginner I don't understand what to do exactly. Please add more details. – Minimus Heximus Oct 21 '20 at 08:08
  • Create a new drawable resource and change the root element to `layer-list`, input the resource file name. In the new drawable resource input the above code with your own icon and sizes. – Lekan May 12 '22 at 09:42
24

Just use Google's MaterialButtons: https://material.io/develop/android/components/buttons/

app:icon
app:iconGravity
app:iconPadding
app:iconSize
PenguinDan
  • 904
  • 7
  • 15
20

update:

Just use the MaterialButton it has icons property, for example:

app:icon
app:iconSize
app:iconGravity
app:iconPadding



<com.google.android.material.button.MaterialButton
    app:icon="@drawable/test"
    app:iconSize="8dp"
    app:iconGravity="end"
    app:iconPadding="8dp"/>
Rasoul Miri
  • 11,234
  • 1
  • 68
  • 78
11

Using a Kotlin Extension:

Add this to keep your code clean and reusable. If you pass nothing or 0 for id, it will clear the drawable. (Button extends TextView)

buttonView.leftDrawable(R.drawable.my_icon, R.dimen.icon_size)

// Button extends TextView
fun TextView.leftDrawable(@DrawableRes id: Int = 0, @DimenRes sizeRes: Int) {
    val drawable = ContextCompat.getDrawable(context, id)
    val size = resources.getDimensionPixelSize(sizeRes)
    drawable?.setBounds(0, 0, size, size)
    this.setCompoundDrawables(drawable, null, null, null)
}
Gibolt
  • 42,564
  • 15
  • 187
  • 127
10

You can set bounds programatically (here), this will look like this

Drawable img = ActivityName.this.getContext().getResources().getDrawable(
            R.drawable.blue_line);
img.setBounds(left, top, right, bottom);
button.setCompoundDrawables(img, null, null, null);
Orbite
  • 505
  • 4
  • 8
7

As long as the icon is a Vector asset, go inside the vector file and modify android:width and android:height to something like @dimen/icon_size. Then define this resource in your dimens.xml files for multiple screen sizes. Works like a charm

OzzyTheGiant
  • 711
  • 8
  • 21
  • this is a good alternative - especially for a single use case. Imagine writing lines of code to achieve such a small change. – Chief May 28 '20 at 16:46
6

Try the following. Declare the drawables as the icons you want to use

    Drawable drawable = getResources().getDrawable(R.mipmap.youricon);
    drawable.setBounds(0, 0, (int) (drawable.getIntrinsicWidth() * 0.6),
            (int) (drawable.getIntrinsicHeight() * 0.6));
    ScaleDrawable sd = new ScaleDrawable(drawable, 0, 40, 40);
    youredittext1.setCompoundDrawables(null, null, sd.getDrawable(), null);
    drawable = getResources().getDrawable(R.mipmap.yourothericon);
    drawable.setBounds(0, 0, (int) (drawable.getIntrinsicWidth() * 0.6),
            (int) (drawable.getIntrinsicHeight() * 0.6));
    sd = new ScaleDrawable(drawable, 0, 40, 40);
    youredittext2.setCompoundDrawables(null, null, sd.getDrawable(), null);
moe_nyc
  • 307
  • 1
  • 4
  • 18
5

Adding to DroidBender's great answer. His solution does not crash on API 21, so it still can be used, even without adding Build.VERSION.SDK_INT code. This is how the solution using a standard image asset looks on API 21 (using text height as the dimension setting).

enter image description here

And this is how it looks on API 23+

enter image description here

It is still a really good option, even if the min API < 23.

seekingStillness
  • 4,833
  • 5
  • 38
  • 68
  • 1
    Well that depends a lot on the drawable, it may simply be hidden, or be enormous. Right now API < 23 is about 15% outside US. – htafoya Oct 16 '18 at 15:29
  • 1
    @htafoya Good point. I guess I should have specifically said image asset. I've updated my post. – seekingStillness Oct 16 '18 at 17:32
  • @seekingStillness No, it will NOT be displayed correctly on all cases on API < 23, i have just check it and my icon was covering the half of the screen. For API < 23 Orbite answer works – CDrosos Oct 11 '20 at 00:20
  • @CDrosos I had mentioned in my answer "using a standard image asset". I suspect you are not using a standard imported image asset from Android Studio. – seekingStillness Oct 11 '20 at 11:12
  • What is a standard image asset? I was using a bitmap png image. Its better to use the other approach below API 23 in my opinion. Better be safe – CDrosos Oct 11 '20 at 11:15
  • Also keep in mind that while this might work in Java and not work in Xamarin.Android. So it's better to be specific – CDrosos Oct 11 '20 at 11:16
4

This solution works for all use cases where you use a vector graphics icon and it is compatible with below 23 versions as well.

Open the drawable icon in xml

Original Icon drawable:

<vector 
    android:height="24dp"
    android:tint="?attr/colorControlNormal" 
    android:viewportHeight="24"
    android:viewportWidth="24" 
    android:width="24dp" 
    xmlns:android="http://schemas.android.com/apk/res/android">
    <path android:fillColor="@android:color/white" android:pathData="M11,18h2v-2h-2v2zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM12,6c-2.21,0 -4,1.79 -4,4h2c0,-1.1 0.9,-2 2,-2s2,0.9 2,2c0,2 -3,1.75 -3,5h2c0,-2.25 3,-2.5 3,-5 0,-2.21 -1.79,-4 -4,-4z"/>
</vector>

Now wrap your path tags with group tag and add attributes scaleX, scaleY, pivotX and pivotY in group tag to shrink the icon size like this :

<vector 
    android:height="24dp"
    android:tint="?attr/colorControlNormal" 
    android:viewportHeight="24"
    android:viewportWidth="24" 
    android:width="24dp" 
    xmlns:android="http://schemas.android.com/apk/res/android">
    <group
        android:scaleX="0.5"
        android:scaleY="0.5"
        android:pivotX="12"
        android:pivotY="12">
        <path
        android:fillColor="@android:color/white"
        android:pathData="M11,18h2v-2h-2v2zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM12,6c-2.21,0 -4,1.79 -4,4h2c0,-1.1 0.9,-2 2,-2s2,0.9 2,2c0,2 -3,1.75 -3,5h2c0,-2.25 3,-2.5 3,-5 0,-2.21 -1.79,-4 -4,-4z"/>
    </group>
</vector>

You can control the size of the icon by changing scaleX and scaleY.

This is useful not only in case of drawables but any place where an icon is used and where it is not easy to find styling solutions to reduce icon size like say an AlertDialogue.

Sid Shinde
  • 238
  • 3
  • 8
3

create new drawable as below and use it in view. We can set width,height,margins for drawable.

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

   <item
    android:width="12dp"
    android:end="3dp"
    android:start="3dp"
    android:top="3dp"
    android:bottom="3dp"
    android:height="12dp"
    android:drawable="@drawable/your_drawable" />

</layer-list>
Tarun Anchala
  • 2,232
  • 16
  • 15