Android: combining text & image on a Button or ImageButton - android

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"
/>

Related

Clickable icon on image

I want to add a clickable “favorite icon ❤️“ on the top of the ImageView for an Android project. I found similar to this in Zillow application as in the attached image. Any help please?
image from Zillow
use checkbox for this, use 2 icon one is favorite (full heart) and the other is an unfavourite icon(heart with the only border) and set In the selector
set selector file in android:button property in the check box
<androidx.appcompat.widget.AppCompatCheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:button="#drawable/selector_checkbox"/>
Here is the selector file,
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true"
android:drawable="#drawable/checkbox_favorite" />
<item
android:state_checked="false"
android:drawable="#drawable/checkbox_unfavourite" />
</selector>
Follow this code ,
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="center"// your scale image on your need!
android:src="your_image" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_baseline_favorite_24"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:clickable="true"// doesnt need just hard code like setOnClick...
android:layout_alignParentEnd="true"
android:layout_margin="16dp"/>
</RelativeLayout>

Android Button with two images and Text

I am trying to build the android app and need to build a button with two images and some text .
here is the example image :
how can i build this button in android ? any help would be appreciated .
Here is some code to get you started. Lets begin with the background. If that background is not provided to you and you have to create it yourself, lets create a custom_button_bg.xml file and add to your drawable folder.
custom_button_bg.xml Note: that I am just doing the basic shape for you. Adjust shadow and corner radius as you wish
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:endColor="#color/teal"
android:startColor="#color/teal"/>
<corners android:radius="4dp"/>
<stroke
android:width="1dp"
android:color="#color/shadow"/>
</shape>
Now simply create your layout, something like below. Just replace the src and labels.
<RelativeLayout
android:layout_width="160dp"
android:layout_height="80dp"
android:gravity="center_vertical"
android:background="#drawable/custom_rounded_white_button">
<ImageView
android:id="#+id/iv_video_cam"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/video_cam"/>
<TextView
android:id="#+id/tv_desc"
android:layout_toRightOf="#+id/iv_video_cam"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="See a Medical \nDoctor Now"/>
<ImageView
android:layout_toRightOf="#+id/tv_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/arrow"/>
</RelativeLayout>
Cheers!
You can use something like this:
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:drawableLeft="#drawable/video_camera"
android:drawableRight="#drawable/right_arrow"
android:text="See a Medical\nDoctor Now"/>
Two Options:
You can utilize setBackgroundDrawable() on your Button to set the background of the button to an image with the icons you want, then your text will appear above the background.
Or you could try and utilize android:drawableLeft="#drawable/yourimage" and/or android:drawableRight="#drawable/yourimage" in your XML file nested in your Button.
HERE you can find more information on drawableRight/Left
I face to same problem in my case below code worked ;)
android:layout_width="370dp"
android:layout_height="62dp"
android:layout_marginTop="100dp"
android:drawableLeft="#drawable/flag_us_little"
android:drawableRight="#drawable/ic_arrow"
android:text="English language"
android:textAllCaps="true"
android:textColor="#color/black"/>
Cheers!
Three steps:
Took a screenshot of the image you provided.
Places the screenshot in the drawable project of my folder and named it "background"
in my layout xml file. set the image as the button background:
<Button
android:layout_width="165dp"
android:layout_height="35dp"
android:background="#drawable/background"
android:textColor="#FFFFFF"
android:id="#+id/button"
android:paddingTop="2sp"
android:drawablePadding="-1sp"
></Button>
Final result:

Place ImageView over Button android

I am trying to place an ImageView over a Button using RelativeLayout. Here is my xml:
<RelativeLayout
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:layout_weight="0.50" >
<Button
android:id="#+id/btnFindDaysInBetween"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/blue_500"
android:text="#string/dt_text_days" />
<ImageView
android:id="#+id/imageview_find_days_in_between"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:contentDescription="#string/empty"
android:src="#drawable/ic_check_circle_white" />
</RelativeLayout>
Here is the image screenshot:
As you can see, the ImageView's src image is not visible. However if i change the button at the back to an ImageView, the image of the top ImageView is visible. Please refer below..
Changed xml:
<RelativeLayout
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:layout_weight="0.50" >
<!--
<Button
android:id="#+id/btnFindDaysInBetween"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/blue_500"
android:text="#string/dt_text_days" />
-->
<ImageView
android:id="#+id/imageview_find_days"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:contentDescription="#string/empty"
android:src="#drawable/ic_send_black" />
<ImageView
android:id="#+id/imageview_find_days_in_between"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:contentDescription="#string/empty"
android:src="#drawable/ic_check_circle_white" />
</RelativeLayout>
Changed xml's screenshot:
What is it that i am doing wrong in the first layout?
The reason is actually very simple. :) We are so caught up thinking in 2D that we overlook the elevation - in Z.
There is nothing wrong with your first layout. The Button simply has a higher elevation than the ImageView - exactly 1dp higher. Therefore, no matter how you arrange the two views, the Button rises above.
A bit of proof:
A Button, by default gets the Widget.Material.Button style:
<!-- Bordered ink button -->
<style name="Widget.Material.Button">
<item name="background">#drawable/btn_default_material</item>
<item name="textAppearance">?attr/textAppearanceButton</item>
<item name="minHeight">48dip</item>
<item name="minWidth">88dip</item>
<item name="stateListAnimator">#anim/button_state_list_anim_material</item>
<item name="focusable">true</item>
<item name="clickable">true</item>
<item name="gravity">center_vertical|center_horizontal</item>
</style>
The attribute that introduces this elevation is android:stateListAnimator. StateListAnimator is similar to StateListDrawable, and provides state change animations. The complete xml is here: Link. But here's the base state of the button:
<!-- base state -->
<item android:state_enabled="true">
<set>
<objectAnimator android:propertyName="translationZ"
android:duration="#integer/button_pressed_animation_duration"
android:valueTo="0"
android:startDelay="#integer/button_pressed_animation_delay"
android:valueType="floatType"/>
<objectAnimator android:propertyName="elevation"
android:duration="0"
android:valueTo="#dimen/button_elevation_material"
android:valueType="floatType" />
</set>
</item>
As you can see, the elevation value for the button is set to #dimen/button_elevation_material:
<dimen name="button_elevation_material">1dp</dimen>
And that's how the ImageView ends up being behind/below the Button.
So, what can we do?
A straight-forward solution would be to set the ImageView's elevation to the same amount - 1dp.
Another solution, which will require a bit of work, is to remove the Button's elevation rather than change ImageView's. Based on the default StateListAnimator, we can create our own - and remove the elevation. Then, in your res/values-v21/styles.xml, define a style that inherits from Widget.Material.Button:
<style name="MyDepressedButtonStyle" parent="android:Widget.Material.Button">
<item name="android:stateListAnimator">#anim/customized_state_animator</item>
</style>
Now, set this style on your Button:
<Button
style="#style/MyDepressedButtonStyle"
....
.... />
Edit:
Actually, we can apply the customized StateListAnimator directly:
<Button
android:stateListAnimator="#anim/customized_state_animator"
....
.... />
No need to take the scenic route!
I found a solution:
simply android:elevation="2dp"
<Button
android:id="#+id/btnAccess"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_gravity="right|center"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imageView4"
android:background="#drawable/or"
android:layout_alignBottom="#+id/btnRegister"
android:layout_centerHorizontal="true"
android:layout_margin="5dp"
android:elevation="2dp" />
Actually it's much easier to just set the StateListAnimator to #null
<Button
...
android:stateListAnimator="#null" />
Source Android 5.0 android:elevation Works for View, but not Button?
Use ImageButton replace Button and set ImageButton background as transparent.
<ImageButton
android:id="#+id/btnFindDaysInBetween"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/blue_500_text"
android:background="#android:color/transparent"
/>
<ImageView
android:id="#+id/imageview_find_days_in_between"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:contentDescription="#string/empty"
android:src="#drawable/ic_check_circle_white" />
You can make a image that has your blue_500 color and text(that is easy to create), then set this image to your ImageButton. After that, your ImageView will see on the top of ImageButton.
Hope this help!
Button is just a TextView with a certain style applied to it, so if you replace Button with TextView you can display an ImageView on top of it. This also works on API < 21.
android:background exists for all the view. As the name suggests this is what is going to be there in the background.
android:src exists for ImageViews and its subclasses. You can think of this as the foreground. Because ImageView is a subclass of View you even have android:background for that.
If the foreground is smaller than background, the background portion which is not covered by the foreground would be visible.
Also, you can use transparency in the foreground in which case the background would be visible(transparently).
You can use BACKGROUND FOR ALL THE VIEWS.. But You can use SRC only for ImageView & ImageButton.....
#Vamsi I tried your both combinations and first one is not working with Button. You have to go through ImageView. This is what I tried with with ImageView:
While I tried to do it with Button and see what was result:
I tried to change the order but all in vain! It seems you have to go with either ImageView or ImageButton.
At the end! You can see what I had tried:
<RelativeLayout
android:layout_height="match_parent"
android:layout_width="match_parent">
<!-- <ImageView
android:id="#+id/btnTest"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="#drawable/ic_launcher_web"
android:contentDescription="#string/app_name"
android:text="#string/app_name" /> -->
<ImageView
android:layout_width="wrap_content"
android:id="#+id/imgView"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:contentDescription="#string/app_name"
android:src="#drawable/ic_launcher" />
<Button
android:id="#+id/btnTest"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/imgView"
android:layout_alignTop="#+id/imgView"
android:text="#string/app_name" />
</RelativeLayout>
I had done same kind of work either with ImageView or ImageButton (probably with ImageView) and tried same approach as you were trying with Button.
Thanks
If you want to get an ImageView on top of a Button, and you are developing for Android API < 21 (for instance, KitKat = 19), the easiest way is to not use a Button at all and use 2 ImageView instead. Why would you want to do that? May be because you defined a drawable shape to make the button look "cooler", so you are already using android:background with that shape.
Ex:
<Button
android:id="#+id/button01"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#drawable/buttonshape"
/>
<ImageView
android:id="#+id/image01"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginTop="10dp"
android:layout_marginStart="10dp"
android:src="#drawable/desiredImageOnTop"
/>
Where #drawable/buttonshape.xml is:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners
android:radius="30dp"
/>
<gradient
android:angle="45"
android:centerColor="#47A891"
android:centerX="35%"
android:endColor="#000000"
android:startColor="#E8E8E8"
android:type="linear"
/>
<padding
android:bottom="0dp"
android:left="0dp"
android:right="0dp"
android:top="0dp"
/>
<size
android:width="100dp"
android:height="100dp"
/>
<stroke
android:width="3dp"
android:color="#878787"
/>
</shape>
In that case, you should replace the Button with an ImageView, change android:background to android:src, and then, in the java code, you just add an OnClickListener as if it was a Button (both controls derive from View, and OnClickListener is a View event). Works like a charm!
Actually, This is not an error, it is a simple design issues. I have been working on it for last 2 hours. And at last get an easy way.
Now, I want to share the code.
<FrameLayout
android:layout_alignParentStart="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<androidx.appcompat.widget.AppCompatButton
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="4dp"
android:background="#drawable/custom_button"
android:paddingLeft="33dp"
android:layout_marginStart="33dp"
android:text="CHECK APPOINTMENT"
android:textAlignment="viewEnd"
android:textSize="18sp"
/>
</LinearLayout>
<androidx.cardview.widget.CardView
android:layout_width="60dp"
android:layout_height="wrap_content"
app:cardCornerRadius="40dp">
<ImageView
android:layout_width="60dp"
android:layout_height="60dp"
android:elevation="2dp"
android:src="#drawable/care_logo"
android:scaleType="fitCenter"
/>
</androidx.cardview.widget.CardView>
</FrameLayout>
It is working.
I placed ImageView on a Button with a diversion of RelativeLayout, hope this helps.
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<View
android:id="#+id/tempview"
android:layout_width="0dp"
android:layout_height="0dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/tempview"
android:background="#drawable/ic_launcher" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/tempview"
android:src="#drawable/img_cancel" />
</RelativeLayout>

Android app layout background shows through controls in layout

I have an Android app with a GridView where each item is a LinearLayout of two Buttons and two TextViews. When I set the LinearLayout's background color to white, the buttons are grey. However, if I change the background color, the surface of the buttons also get tinted with that color. How can I prevent this?
Example with strong color:
Buttons should be light gray, not reddish-gray.
Grid item layout XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"
android:background="#drawable/grid_cell_max">
<Button
android:layout_width="50dp"
android:layout_height="50dp"
android:text="+"
android:includeFontPadding="false"
android:paddingBottom="4dp"
android:paddingTop="4dp"
android:id="#+id/buttonPlus"
android:layout_gravity="center_vertical"
android:textSize="24sp"
android:gravity="center_vertical|center_horizontal" />
<Button
android:layout_width="50dp"
android:layout_height="50dp"
android:text="-"
android:textSize="24sp"
android:includeFontPadding="false"
android:paddingBottom="4dp"
android:paddingTop="4dp"
android:id="#+id/buttonMinus"
android:layout_gravity="center_vertical"
android:gravity="center_vertical|center_horizontal" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:paddingTop="1dp"
android:paddingBottom="2dp"
android:orientation="vertical">
<TextView
android:id="#+id/buildingTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:lines="1"
android:shadowDx="1"
android:shadowDy="1"
android:shadowRadius="2"
android:shadowColor="#android:color/darker_gray"
android:ellipsize="end"
android:textSize="15sp"
android:textStyle="bold"/>
<TextView
android:id="#+id/buildingInfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="11sp"
android:lines="2"
android:ellipsize="end"
android:lineSpacingExtra="-2dp"/>
</LinearLayout>
</LinearLayout>
drawable/grid_cell_max.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape= "rectangle" >
<solid android:color="#ffe6ffe3"/>
<stroke android:width="1dp" android:color="#c0c0c0"/>
</shape>
Unfortunately, I don't think there's an easy way to do this. The way I resolved this issue was:
Use Android holo colors generator to generate new resources:
Make sure to select the color you need for your button (under 'Theme Name')
Make sure to switch 'Colored Button' to 'Yes'
Download the archive and unpack it.
Merge only the drawable folders from the unpacked project into yours (only the button image resources and the button selector xml file - located in drawable)
Set the background of your buttons to:
android:background="#drawable/apptheme_btn_default_holo_light"
You'll now have a opaque button with the color you selected from the android holo colors generator.
If you want all your app buttons to behave the same way, you'll have to update the app theme. To do this, follow the steps above and afterwards update your 'styles.xml' file:
<style name="AppTheme" parent="android:Theme.Holo.Light">
<item name="android:buttonStyle">#style/ButtonAppTheme</item>
</style>
<style name="ButtonAppTheme" parent="android:Widget.Holo.Light.Button">
<item name="android:background">#drawable/apptheme_btn_default_holo_light</item>
</style>
Also, if you do this, you can remove the button background from xml. I couldn't find another solution if you want to keep the 'Theme.Holo.Light' app theme.

Changing background or foreground button color dynamically in android

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.

Categories

Resources