I'm trying to my custom RadioButton that I trying to make to look like this:
So I did custom drawables that respond to the RadioButton status and used it as background. This is alright.
The problem is that I'm not been able to center the images that I set through the android:button atribute.
Here is how I'm trying to use it in my layout.
<RadioGroup
android:id="#+id/presenter_options"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="4dp"
android:gravity="center"
>
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:button="#drawable/cluster_centered"
android:gravity="center"
android:padding="8dp"
android:background="#drawable/presenter_radiobutton_left"
/>
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="8dp"
android:background="#drawable/presenter_radiobutton_right"
android:button="#drawable/fire"
/>
</RadioGroup>
With this I'm getting this as result:
I've already tried to define a drawable that sets the gravity to center, but nothing changed. Here is the custom drawable:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<bitmap android:src="#drawable/cluster" android:gravity="center"/>
</item>
</selector>
So, how could I center the button images?
PS: I can't set each kind of button as background because it'll be dynamic in the future, so the only thing that could be in background is the blue shape.
My solution was to set android:button=#null, then set the image that I want into the android:drawableLeft attribute. So my RadioButton code is like this:
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="8dp"
android:background="#drawable/presenter_radiobutton_left"
android:button="#null"
android:drawableLeft="#drawable/fire"
/>
"on center" solution is
...
<RadioButton>
...
android:button="#null"
android:foreground="#drawable/your_selector_for_center_drawable"
android:background="#drawable/your_selector_for_background_drawable"
android:foregroundGravity="center"
Related
I have many RadioButtons in my app. The RadioButtons are too big for me. Is there any way to make them smaller?
One quick hacky solution is to scale the button down:
<RadioButton
android:scaleX="0.5"
android:scaleY="0.5" />
This works great for going smaller.
For going larger, this tends to cause some clipping from the container View, so you'll likely have to hardcode the height/width of the RadioGroup to fit the scaled buttons. The button drawable can also get noticeably pixelated the larger you go, so it's not really great if you want something 3x larger...
you can use scalex and scaley properties , then use translationX and translationY to put it in the radiobutton windows.
<RadioButton
android:id="#+id/rbtnfkilo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:scaleX="1.4"
android:scaleY="1.4"
android:text="Kilogram"
android:textColor="#fff"
android:textSize="18sp"
android:translationX="24dp" />
It can be done but is not as simple as setting the Layout_Width and Layout_height as with EditTexts, Buttons etc. To modify the size/looks of a view like a checkbox/radio button use the "Background" and "Button" properties to specify your own drawables.
This is an older page, and the locations are different now, but this'll give you an idea :
http://www.anddev.org/tutorial_change_look_of_checkbox-t4553.html
Can't be done, the radio button is a built-in control component and as such its size is fixed.
I relpaced RadioButton with ToggleButton and applied same style. I did override background and button.
<ToggleButton
android:id="#+id/btnToggle1"
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_weight="1"
android:checked="true"
style="#style/ToggleButtonStyle"
android:button="#null"
android:textOn="#string/btnTitle"
android:textOff="#string/btnTitle"/>
and style:
<style name="ToggleButtonStyle">
<item name="android:background">#drawable/background_radiobutton</item>
<item name="android:textColor">#color/selector_text_radiobutton</item>
<item name="android:textAppearance">#null</item>
</style>
Works for me - looks the same, but with custom height.
If your RadioButton is in the RadioGroup, you will need to customize listener, check
Android: How to get a radiogroup with togglebuttons?
Currently, Android Vector Asset Studio have icons for unchecked, checked radio button.
You can import this vector then change the color by change android:tint inside the vector xml
Then set the background for RadioButton like
bg_radio_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="false" android:drawable="#drawable/ic_baseline_radio_button_unchecked_24" />
<item android:state_checked="true" android:drawable="#drawable/ic_baseline_radio_button_checked_24" />
</selector>
..xml
<androidx.appcompat.widget.AppCompatRadioButton
android:layout_width="#dimen/dp_24"
android:layout_height="#dimen/dp_24"
android:background="#drawable/bg_radio_selector"
android:button="#null" />
Now you are able to change the size of RadioButton to any size you want but maybe it hard to click because the click area is quite small.
To increase the click area, we can use this function (note that padding will not work because we use the background property for RadioButton) (solution from How to increase hit area of Android button without scaling background?)
fun View.increaseTouchArea(pixel: Int) {
val parent = parent as View
parent.post {
val rect = Rect()
getHitRect(rect)
rect.top -= pixel
rect.left -= pixel
rect.bottom += pixel
rect.right += pixel
parent.touchDelegate = TouchDelegate(rect, this)
}
}
and
yourRadioButton.increaseTouchArea(context.resources.getDimensionPixelOffset(R.dimen.dp_12))
There is an alternative approach to change the size.
Import radio button checked and unchecked from vector asset.
Create three drawable
radio_button_check
specify any width and height
radio_button_uncheck
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:width="60dp"
android:height="60dp"
android:drawable="#drawable/ic_radio_button_unchecked" />
</layer-list>
custom_radio_button
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/radio_button_check" android:state_checked="true"></item>
<item android:drawable="#drawable/radio_button_uncheck"></item>
</selector>
Radio button
In radio Button
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:button="#drawable/custom_radio_button"
android:paddingLeft="10dp"
android:textSize="39dp"
android:text="1" />
In case to change the text size use "android:textSize" property
In image first one is the custom radio button and second one is default one
I found one workaround for this
we need to use this text/symbol ⭘ and ◉ instead of radio button and add radio button functionality to them.
EXAMPLE:
first create Linear layout for button text and title text
XML
<LinearLayout
android:id="#+id/btn1Layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="⭘"
android:textSize="34sp"
android:textColor="#ffffff"
android:layout_marginStart="25dp"
/>
<TextView
android:id="#+id/btn1txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_marginTop="2dp"
android:text="Option 1"
android:layout_marginStart="3dp"
android:textSize="16sp"
android:textColor="#ffffff"
/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginLeft="25dp"
android:background="#android:color/darker_gray"/>
<LinearLayout
android:id="#+id/btn2Layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="top|fill_horizontal"
android:orientation="horizontal">
<TextView
android:id="#+id/btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="⭘"
android:textSize="34sp"
android:textColor="#ffffff"
android:layout_marginStart="25dp"
/>
<TextView
android:id="#+id/btn2txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_marginTop="2dp"
android:text="Option 2"
android:layout_marginStart="3dp"
android:textSize="16sp"
android:textColor="#ffffff"
/>
</LinearLayout>
LinearLayout btn1Layout = findViewById(R.id.btn1Layout);
LinearLayout btn2Layout = findViewById(R.id.btn2Layout);
TextView btn1 = (TextView) findViewById(R.id.btn1);
TextView btn2 = (TextView) findViewById(R.id.btn2);
btn1.setText(⭘);
btn2.setText(⭘);
if(selectedId != null) {
TextView selectedBtn = (TextView) findViewById(selectedId);
selectedBtn.setText(◉);
}
then set click listners to the all Layouts for updating btn symbols.
btn1Layout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
selectedId = btn1.getId();
btn1.setText(◉);
btn2.setText(⭘);
}
});
<RadioGroup android:layout_width="fill_parent"
android:layout_height="50dp"
android:orientation="horizontal"
android:checkedButton="#+id/first">
<RadioButton android:id="#+id/first"
android:width="50dp"
android:height="50dp"
android:button="#drawable/button_radio"/>
<RadioButton android:id="#+id/second"
android:width="50dp"
android:height="50dp"
android:button="#drawable/button_radio"/>
<RadioButton android:id="#+id/third"
android:width="50dp"
android:height="50dp"
android:button="#drawable/button_radio"/>
<RadioButton android:id="#+id/fourth"
android:width="50dp"
android:height="50dp"
android:button="#drawable/button_radio"/>
</RadioGroup>
As in the title - is it possible to make a titled border around RadioGroup? Or at least a plain border ...
Thanks
Titled border, I don't know...You might want to just add a TextView widget above the border.
But for a plain border, here's how I put a border around my radio group:
Here is my basic radio group (has three buttons, horizontal)
<RadioGroup android:id="#+id/myRadioLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="38dp"
android:orientation="horizontal"
android:elevation="24dp">
<RadioButton android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/radioBtn1"
android:text="RadioButton1" android:checked="true"
style="#android:style/Widget.CompoundButton.RadioButton"
android:textSize="14sp">
</RadioButton>
<RadioButton android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/radioBtn2"
android:text="RadioButton2"
style="#android:style/Widget.CompoundButton.RadioButton"
android:textSize="14sp">
</RadioButton>
<RadioButton android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/radioBtn3"
android:text="RadioButton3" android:checked="true"
style="#android:style/Widget.CompoundButton.RadioButton"
android:textSize="14sp">
</RadioButton>
</RadioGroup>
So, if I want a border surrounding my radio button group, I add an xml file to my drawable folder. Let's call it "border.xml".
Here is the code for border.xml:
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke android:width="5px" android:color="#000000" />
</shape>
Then, you add the following code to your radio group xml:
<RadioGroup android:id="#+id/myRadioLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="38dp"
android:orientation="horizontal"
android:background="#drawable/border"
android:elevation="24dp">
And a border should appear around your radio group. Note that you can vary the attributes to get different shapes for the border, gradients, rounded corners, etc. possible attributes for the shape element, can be found here:
https://developer.android.com/guide/topics/resources/drawable-resource.html#Shape
Suppose I have a footer like the following in my app, defined in a XML file such as footer.xml:
<LinearLayout android:id="#+id/llfooter"
android:layout_weight="1" android:layout_width="fill_parent"
android:orientation="horizontal" android:layout_height="0dp"
android:visibility="visible" android:background="#drawable/fbg"
android:weightSum="5.0" android:gravity="center"
android:layout_margin="0dp">
<Button android:id="#+id/home" android:layout_height="wrap_content"
android:layout_width="wrap_content" android:layout_weight="1"
android:background="#drawable/home" android:textColor="#FFFFFF"
android:padding="10px"></Button>
<Button android:id="#+id/issue" android:layout_height="wrap_content"
android:layout_width="wrap_content" android:layout_weight="1"
android:background="#android:drawable/ic_menu_send" android:textColor="#FFFFFF"
android:padding="10px"></Button>
<Button android:id="#+id/browse" android:layout_height="wrap_content"
android:layout_width="wrap_content" android:layout_weight="1"
android:background="#android:drawable/ic_menu_slideshow" android:textColor="#FFFFFF"
android:padding="10px"></Button>
<Button android:id="#+id/search" android:layout_height="wrap_content"
android:layout_width="wrap_content" android:layout_weight="1"
android:background="#drawable/search" android:textColor="#FFFFFF"
android:padding="10px"></Button>
<Button android:layout_height="wrap_content" android:id="#+id/favorite"
android:background="#drawable/favorite" android:layout_width="wrap_content"
android:focusable="true"
android:clickable="true"
android:layout_weight="1"
android:textColor="#FFFFFF" android:padding="10px"></Button>
</LinearLayout>
Now, the problem is that home, issue, browse, etc. are PNG icons, and when I tap on them, user can't have feedback of touching, because they stay unchanged.
I would like to change background colour on pressing them (e.g. just a bit lighter). I know I can write down XML drawables () one per button, such as the following
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:state_pressed="true"
android:drawable="#drawable/bgalt" />
<item android:state_focused="false" android:state_pressed="true"
android:drawable="#drawable/bgalt" />
<item android:drawable="#drawable/bgnorm" />
</selector>
.. but if I have 10 buttons (say, 5 for footer, 5 for header) I should create other 10 buttons with altered background (so more work with graph editor and .apk heavier because of more raster icons.. ).
Is there a way to create (even in java) a ligher color "onClick" and normal color "onRelease" instead, with only one icon per feature in resources?
Any suggestions?
Tnx in advance.
Gabo
Use an ImageButton, and set the android:src parameter to the button drawable with a transparent background, then set the android:background value to a selector drawable that changes color when selected for example.
That way you have a set of drawables for your icons and one drawable only for the background which changes according to the state of your button
you can get button bitmap in onTouch in the code and change color, but it's bad idea.
selector is best solution.
I have many RadioButtons in my app. The RadioButtons are too big for me. Is there any way to make them smaller?
One quick hacky solution is to scale the button down:
<RadioButton
android:scaleX="0.5"
android:scaleY="0.5" />
This works great for going smaller.
For going larger, this tends to cause some clipping from the container View, so you'll likely have to hardcode the height/width of the RadioGroup to fit the scaled buttons. The button drawable can also get noticeably pixelated the larger you go, so it's not really great if you want something 3x larger...
you can use scalex and scaley properties , then use translationX and translationY to put it in the radiobutton windows.
<RadioButton
android:id="#+id/rbtnfkilo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:scaleX="1.4"
android:scaleY="1.4"
android:text="Kilogram"
android:textColor="#fff"
android:textSize="18sp"
android:translationX="24dp" />
It can be done but is not as simple as setting the Layout_Width and Layout_height as with EditTexts, Buttons etc. To modify the size/looks of a view like a checkbox/radio button use the "Background" and "Button" properties to specify your own drawables.
This is an older page, and the locations are different now, but this'll give you an idea :
http://www.anddev.org/tutorial_change_look_of_checkbox-t4553.html
Can't be done, the radio button is a built-in control component and as such its size is fixed.
I relpaced RadioButton with ToggleButton and applied same style. I did override background and button.
<ToggleButton
android:id="#+id/btnToggle1"
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_weight="1"
android:checked="true"
style="#style/ToggleButtonStyle"
android:button="#null"
android:textOn="#string/btnTitle"
android:textOff="#string/btnTitle"/>
and style:
<style name="ToggleButtonStyle">
<item name="android:background">#drawable/background_radiobutton</item>
<item name="android:textColor">#color/selector_text_radiobutton</item>
<item name="android:textAppearance">#null</item>
</style>
Works for me - looks the same, but with custom height.
If your RadioButton is in the RadioGroup, you will need to customize listener, check
Android: How to get a radiogroup with togglebuttons?
Currently, Android Vector Asset Studio have icons for unchecked, checked radio button.
You can import this vector then change the color by change android:tint inside the vector xml
Then set the background for RadioButton like
bg_radio_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="false" android:drawable="#drawable/ic_baseline_radio_button_unchecked_24" />
<item android:state_checked="true" android:drawable="#drawable/ic_baseline_radio_button_checked_24" />
</selector>
..xml
<androidx.appcompat.widget.AppCompatRadioButton
android:layout_width="#dimen/dp_24"
android:layout_height="#dimen/dp_24"
android:background="#drawable/bg_radio_selector"
android:button="#null" />
Now you are able to change the size of RadioButton to any size you want but maybe it hard to click because the click area is quite small.
To increase the click area, we can use this function (note that padding will not work because we use the background property for RadioButton) (solution from How to increase hit area of Android button without scaling background?)
fun View.increaseTouchArea(pixel: Int) {
val parent = parent as View
parent.post {
val rect = Rect()
getHitRect(rect)
rect.top -= pixel
rect.left -= pixel
rect.bottom += pixel
rect.right += pixel
parent.touchDelegate = TouchDelegate(rect, this)
}
}
and
yourRadioButton.increaseTouchArea(context.resources.getDimensionPixelOffset(R.dimen.dp_12))
There is an alternative approach to change the size.
Import radio button checked and unchecked from vector asset.
Create three drawable
radio_button_check
specify any width and height
radio_button_uncheck
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:width="60dp"
android:height="60dp"
android:drawable="#drawable/ic_radio_button_unchecked" />
</layer-list>
custom_radio_button
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/radio_button_check" android:state_checked="true"></item>
<item android:drawable="#drawable/radio_button_uncheck"></item>
</selector>
Radio button
In radio Button
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:button="#drawable/custom_radio_button"
android:paddingLeft="10dp"
android:textSize="39dp"
android:text="1" />
In case to change the text size use "android:textSize" property
In image first one is the custom radio button and second one is default one
I found one workaround for this
we need to use this text/symbol ⭘ and ◉ instead of radio button and add radio button functionality to them.
EXAMPLE:
first create Linear layout for button text and title text
XML
<LinearLayout
android:id="#+id/btn1Layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="⭘"
android:textSize="34sp"
android:textColor="#ffffff"
android:layout_marginStart="25dp"
/>
<TextView
android:id="#+id/btn1txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_marginTop="2dp"
android:text="Option 1"
android:layout_marginStart="3dp"
android:textSize="16sp"
android:textColor="#ffffff"
/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginLeft="25dp"
android:background="#android:color/darker_gray"/>
<LinearLayout
android:id="#+id/btn2Layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="top|fill_horizontal"
android:orientation="horizontal">
<TextView
android:id="#+id/btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="⭘"
android:textSize="34sp"
android:textColor="#ffffff"
android:layout_marginStart="25dp"
/>
<TextView
android:id="#+id/btn2txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_marginTop="2dp"
android:text="Option 2"
android:layout_marginStart="3dp"
android:textSize="16sp"
android:textColor="#ffffff"
/>
</LinearLayout>
LinearLayout btn1Layout = findViewById(R.id.btn1Layout);
LinearLayout btn2Layout = findViewById(R.id.btn2Layout);
TextView btn1 = (TextView) findViewById(R.id.btn1);
TextView btn2 = (TextView) findViewById(R.id.btn2);
btn1.setText(⭘);
btn2.setText(⭘);
if(selectedId != null) {
TextView selectedBtn = (TextView) findViewById(selectedId);
selectedBtn.setText(◉);
}
then set click listners to the all Layouts for updating btn symbols.
btn1Layout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
selectedId = btn1.getId();
btn1.setText(◉);
btn2.setText(⭘);
}
});
<RadioGroup android:layout_width="fill_parent"
android:layout_height="50dp"
android:orientation="horizontal"
android:checkedButton="#+id/first">
<RadioButton android:id="#+id/first"
android:width="50dp"
android:height="50dp"
android:button="#drawable/button_radio"/>
<RadioButton android:id="#+id/second"
android:width="50dp"
android:height="50dp"
android:button="#drawable/button_radio"/>
<RadioButton android:id="#+id/third"
android:width="50dp"
android:height="50dp"
android:button="#drawable/button_radio"/>
<RadioButton android:id="#+id/fourth"
android:width="50dp"
android:height="50dp"
android:button="#drawable/button_radio"/>
</RadioGroup>
I'm trying to have an image (as the background) on a button and add dynamically, depending on what's happening during run-time, some text above/over the image.
If I use ImageButton I don't even have the possibility to add text.
If I use Button I can add text but only define an image with android:drawableBottom and similar XML attributes as defined here.
However these attributes only combine text & image in x- and y-dimensions, meaning I can draw an image around my text, but not below/under my text (with the z-axis defined as coming out of the display).
Any suggestions on how to do this? One idea would be to either extend Button or ImageButton and override the draw()-method. But with my current level of knowledge I don't really know how to do this (2D rendering). Maybe someone with more experience knows a solution or at least some pointers to start?
For users who just want to put Background, Icon-Image and Text in one Button from different files: Set on a Button background, drawableTop/Bottom/Rigth/Left and padding attributes.
<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>
For more sophisticated arrangement you also can use RelativeLayout (or any other layout) and make it clickable.
Tutorial: Great tutorial that covers both cases: http://izvornikod.com/Blog/tabid/82/EntryId/8/Creating-Android-button-with-image-and-text-using-relative-layout.aspx
There's a much better solution for this problem.
Just take a normal Button and use the drawableLeft and the gravity attributes.
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:drawableLeft="#drawable/my_btn_icon"
android:gravity="left|center_vertical" />
This way you get a button which displays a icon in the left side of the button and the text at the right site of the icon vertical centered.
You can call setBackground() on a Button to set the background of the button.
Any text will appear above the background.
If you are looking for something similar in xml there is:
android:background attribute which works the same way.
<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" />
Just use a LinearLayout and pretend it's a Button - setting background and clickable is the key:
<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>
just replace
android:background="#drawable/icon"
with
android:background="#android:color/transparent"
android:drawableTop="#drawable/[your background image here]"
izz a pretty good trick.. ;)
I took a different approach from the ones stated here, and it is working really well, so I wanted to share it.
I'm using a Style to create a custom button with image at the left and text at the center-right. Just follow the 4 "easy steps" below:
I. Create your 9 patches using at least 3 different PNG files and the tool you have at: /YOUR_OWN_PATH/android-sdk-mac_x86/tools/./draw9patch. After this you should have:
button_normal.9.png, button_focused.9.png and button_pressed.9.png
Then download or create a 24x24 PNG icon.
ic_your_icon.png
Save all in the drawable/ folder on your Android project.
II. Create a XML file called button_selector.xml in your project under the drawable/ folder. The states should be like this:
<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. Go to the values/ folder and open or create the styles.xml file and create the following XML code:
<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 is a "child style" because it is extending ButtonNormalText (the "parent style").
Note that changing the drawableLeft in the ButtonNormalTextWithIcon style, to drawableRight, drawableTop or drawableBottom you can place the icon in other position with respect to the text.
IV. Go to the layout/ folder where you have your XML for the UI and go to the Button where you want to apply the style and make it look like this:
<Button android:id="#+id/buttonSubmit"
android:text="#string/button_submit"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="#style/ButtonNormalTextWithIcon" ></Button>
And... voilà! You got your button with an image at the left side.
For me, this is the better way to do it! because doing it this way you can manage the text size of the button separately from the icon you want to display and use the same background drawable for several buttons with different icons respecting the Android UI Guidelines using styles.
You can also create a theme for your App and add the "parent style" to it so all the buttons look the same, and apply the "child style" with the icon only where you need it.
Important Update
Don't use normal android:drawableLeft etc... with vector drawables, else it
will crash in lower API versions. (I have faced it in live app)
For vector drawable
If you are using vector drawable, then you must
Have you migrated to AndroidX? if not you must migrate to AndroidX first. It is very simple, see what is androidx, and how to migrate?
It was released in version 1.1.0-alpha01, so appcompat version should be at least 1.1.0-alpha01. Current latest version is 1.1.0-alpha02, use latest versions for better reliability, see release notes - link.
implementation 'androidx.appcompat:appcompat:1.1.0-alpha02'
Use AppCompatTextView/AppCompatButton/AppCompatEditText
Use app:drawableLeftCompat, app:drawableTopCompat, app:drawableRightCompat, app:drawableBottomCompat, app:drawableStartCompat and app:drawableEndCompat
For regular drawable
If you don't need vector drawable, then you can
use android:drawableLeft, android:drawableRight, android:drawableBottom, android:drawableTop
You can use either regular TextView, Button & EditText or AppCompat classes.
You can achieve Output like below -
<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"
/>
You can use drawableTop (also drawableLeft, etc) for the image and set text below the image by adding the 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" />
MaterialButton has support for setting an icon and aligning it to the text:
<com.google.android.material.button.MaterialButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="My button"
app:icon="#drawable/your_icon"
app:iconGravity="textStart"
/>
app:iconGravity can also be to start / end if you want to align the icon to the button instead of the text inside it.
Since version 1.5.0-beta01, app:iconGravity can also be top / textTop (commit)
<Button
android:id="#+id/groups_button_bg"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="Groups"
android:drawableTop="#drawable/[image]" />
android:drawableLeft
android:drawableRight
android:drawableBottom
android:drawableTop
http://www.mokasocial.com/2010/04/create-a-button-with-an-image-and-text-android/
Probably my solution will suit for a lot of users, I hope so.
What I am suggesting it is making TextView with your style. It works for me perfectly, and has got all features, like a button.
First of all lets make button style, which you can use everywhere...I am creating 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>
Secondly,
Lets create a textview button.
<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" />
And this is a result. Then style your custom button with any colors or any other properties and margins. Good luck
This code works for me perfectly
<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>
To combine Button and drawableTop and still get the click response, you can use button style #style/Widget.AppCompat.Button.Borderless to make it transparent.
<Button
android:id="#+id/settings"
style="#style/Widget.AppCompat.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableTop="#drawable/ic_baseline_settings_24"
android:drawableTint="?attr/colorPrimary"
android:text="#string/settings"
android:textColor="?attr/colorPrimary" />
<Button android:id="#+id/myButton"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:text="Image Button"
android:drawableTop="#drawable/myimage"
/>
Or you can programmatically:
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
You can use this:
<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" />
in that i have put an image as background and also added text..!
Make a fake button.
It's really the only way
<FrameLayout
android:id="#+id/fake_button"
android:layout_width=" .. "
android:layout_height=" .. "
android:background="#android:color/transparent"
android:clickable="true"
android:onClick="tappedNext">
<ImageView
android:id="#+id/fake_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/your_amazing_drawable" />
<TextView
android:id="#+id/fake_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="Next"
android:fontFamily="#font/ .. "
android:textColor="#color/ .. "
android:textSize=" .. " />
</FrameLayout>
<ImageView
android:id="#+id/iv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="#drawable/temp"
/>