How to center icon and text in a android button with width set to "fill parent"
Solution 1
All the previous answers seem to be outdated
You can use the MaterialButton
now which lets setting the icon gravity.
<com.google.android.material.button.MaterialButton
android:id="@+id/btnDownloadPdf"
android:layout_width="0dp"
android:layout_height="56dp"
android:layout_margin="16dp"
android:gravity="center"
android:textAllCaps="true"
app:backgroundTint="#fc0"
app:icon="@drawable/ic_pdf"
app:iconGravity="textStart"
app:iconPadding="10dp"
app:iconTint="#f00"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:text="Download Pdf" />
For using the material components you will obviously need to:
Add a dependency
implementation 'com.google.android.material:material:1.3.0-alpha01'
(use latest version)
Make your theme extend Material Components theme
<style name="AppTheme" parent="Theme.MaterialComponents.Light">
...
</style>
In case you cannot do so, extend it from the Material Bridge theme
<style name="AppTheme" parent="Theme.MaterialComponents.Light.Bridge">
...
</style>
Solution 2
android:drawableLeft is always keeping android:paddingLeft as a distance from the left border. When the button is not set to android:width="wrap_content", it will always hang to the left!
With Android 4.0 (API level 14) you can use android:drawableStart attribute to place a drawable at the start of the text. The only backward compatible solution I've come up with is using an ImageSpan to create a Text+Image Spannable:
Button button = (Button) findViewById(R.id.button);
Spannable buttonLabel = new SpannableString(" Button Text");
buttonLabel.setSpan(new ImageSpan(getApplicationContext(), R.drawable.icon,
ImageSpan.ALIGN_BOTTOM), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
button.setText(buttonLabel);
In my case I needed to also adjust the android:gravity attribute of the Button to make it look centered:
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="32dp"
android:minWidth="150dp"
android:gravity="center_horizontal|top" />
Solution 3
I know I am late in answering this question, but this helped me:
<FrameLayout
android:layout_width="match_parent"
android:layout_height="35dp"
android:layout_marginBottom="5dp"
android:layout_marginTop="10dp"
android:background="@color/fb" >
<Button
android:id="@+id/fbLogin"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="@null"
android:drawableLeft="@drawable/ic_facebook"
android:gravity="center"
android:minHeight="0dp"
android:minWidth="0dp"
android:text="FACEBOOK"
android:textColor="@android:color/white" />
</FrameLayout>
I found this solution from here: Android UI struggles: making a button with centered text and icon
Solution 4
I used LinearLayout instead of Button. The OnClickListener, which I need to use works fine also for LinearLayout.
<LinearLayout
android:id="@+id/my_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/selector"
android:gravity="center"
android:orientation="horizontal"
android:clickable="true">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="15dp"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:src="@drawable/icon" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Text" />
</LinearLayout>
Solution 5
I adjust it by adding padding left and right as follows:
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/btn_facebookact_like"
android:text="@string/btn_facebookact_like"
android:textColor="@color/black"
android:textAllCaps="false"
android:background="@color/white"
android:drawableStart="@drawable/like"
android:drawableLeft="@drawable/like"
android:gravity="center"
android:layout_gravity="center"
android:paddingLeft="40dp"
android:paddingRight="40dp"
/>
jloriente
Software developer interested in: nodejs, Java, Android, iOS, Web and Mobile
Updated on July 08, 2022Comments
-
jloriente almost 2 years
I want to have an Android Button with icon+text centered inside it. I'm using the drawableLeft attribute to set the image, this works well if the button has a width of
"wrap_content"
but I need to stretch to max width so I use width"fill_parent"
. This moves my icon straight to the left of the button and I want both icon and text centered inside the button.I've try setting up the padding but this only allows to give a fixed value so it is not what I need. I need to have icon+text aligned in the center.
<Button android:id="@+id/startTelemoteButton" android:text="@string/start_telemote" android:drawableLeft="@drawable/start" android:paddingLeft="20dip" android:paddingRight="20dip" android:width="fill_parent" android:heigh="wrap_content" />
Any suggestions on how I could achieve that?
-
jloriente over 13 yearsIt's possible that there is not an easy solution for this? Do I have to try with a 9patch button img with the icon in there?
-
Octavian Damiean over 13 yearsThis might be a solution. Is the button text going to be localized or static?
-
jloriente over 13 yearsIt's localized. There is not any other solution for this? I managed to do it with a 9 patch but having problems when changing locale.
-
Francesco almost 10 yearsWhat about using a Button with drawable TOP and adding some padding to it?
-
Muhammad Babar over 9 yearsbad framework design
-
-
Peter Ajtai over 12 yearsDoesn't work for me. It centers the text, but the drawableLeft remains on the very left.
-
Peter Ajtai over 12 yearsIt doesn't work. The text is somewhat centered but the drawableLeft sticks to the left side.
-
devanshu_kaushik over 12 yearsYou have to declare the icon and text under the same parent, use android:gravity = "centre" for the parent
-
Stan Kurdziel over 11 yearsThis approach can work well. In my case, all I needed was a RelativeLayout containing a TextView. The RelativeLayout got the background, the TextView gets the drawableLeft icon. Then in the code: attach onClickListener to the RelativeLayout and findViewById for the TextView separately if needed
-
AlexD over 11 yearsNice. The last line should be
button.setText(buttonLabel)
-
Lukas Knuth about 11 yearsYou can include code in your answer, which should be the preferred way (if it's not too long), as links might die over time-
-
GLee over 10 yearsUnicode has an extensive set of character icons that are compatible with strings in Android. If you can find an acceptable one, this is a simple solution, and it has the added bonus that it will scale with text size. For instance, it has an envelope for an email icon and a couple of different phones for a call button.
-
Craig McMahon over 10 yearsThis
ImageSpan
solution is wonderful for solving the problem of creating aButton
subclass capable of displaying either an image or text. Thanks! -
muetzenflo over 10 yearsThis is a good idea, but a bad solution. You can achieve the same thing with just one TextView using the drawableLeft-attribute. This enables you to view a drawable to the left of the text.
-
Ankit Popli over 10 years@muetzenflo yup, that's right. but when you make the textView match the parent width your drawable will move to extreme left even if you center your text. please let me know if i'm wrong. and the question is about that only.
-
muetzenflo over 10 yearsah sorry..I came here for exactly this problem and lost focus after trying out too many things :) Guess I didn't see the forest for the trees. My fault!
-
Justin over 9 yearsI'm confused how this worked for anyone, for me it draws 2 icons... one way to the left, and one directly in the center which displays on top of the text.
-
Clive Jefferies over 9 yearsThe problem with this is that the button is not the width of the frame layout.
-
M Dapp over 9 yearsdrawableStart won't work. See this thread: stackoverflow.com/questions/15350990/… Also, it seems that when you set the text using a spannable, the style is ignored.
-
Alex Semeniuk over 9 yearsNot very accurate but I take it
-
Tushar Pandey about 9 yearsQuestion : AnyThing to center ImageSpan.
-
Renetik about 9 yearsNow I see that I was not alone with this solution :)
-
MistaGreen almost 9 yearsThanks! That's what I was looking for.
-
Silvia H almost 9 yearsdrawableStart doesn't work, and it was added in API level 17 to support rtl
-
Youngjae over 8 yearsFirst suggested structure gives "Button cannot be cast to ViewGroup" Exception.
-
Reprator about 8 yearswould u please help me in this question, stackoverflow.com/questions/35912539/…, with your answer i am very close to it but two drawables appears
-
android developer almost 8 yearsThis didn't work for me at all. Can you please show an example? Maybe I don't use it correctly
-
soshial about 7 yearsThis will not work on many screens, only on the one, for which
android:paddingLeft
worked. -
CoolMind about 6 yearsThis solution places drawable in the center of a button, just over centered text.
-
CoolMind about 6 yearsThis solution places an icon over first symbol of a text and ignores padding. It ignores vertical alignment. Author preferred to add spaces (" ") before button text.
-
CoolMind about 6 yearsIt shifts a text right, but not enough (an image overlaps the text). Also, as other custom view's solutions, it doesn't accept long text right.
-
Arrie over 5 yearsThe paddingLeft and paddingRight was that helped me with my centering. upvoting for easy solution.
-
Jacks over 5 yearsHow do you manage the fact that your width is dynamic ? If you rotate your screen, all your icons won't be centered right ? I'm facing this issue actually
-
Dody Rachmat Wicaksono about 4 yearsthis is the best answer!
-
Black_Zerg almost 4 yearsThanks! You saved my day! Works fine
-
Lumii about 3 yearsInstead of having to make change to entire app theme, you may just apply the theme only for the button itself by using app:theme on MaterialButton tag