Android add border to button without losing material theme (using drawable) - android

I have a simple button
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/add"
android:backgroundTint="#color/add_bg"
android:textColor="#color/add_fg"
<!--android:borderColor?="#color/button_border"-->
android:text="#string/add"/>
I would like to have white background, blue text and blue border around. I am aware that I can achieve that through a drawable as shown here and in numerous other places. However I have observed that if you add a drawable to the button then it will lose all of its material properties (such as shadow and also upon clicking having the fancy ripple animation). So how would I add a border around the button without losing the material theme animations (shadow and tipple animation on click)?

Most of the items that android comes with are simply a pre-packaged set of attributes.
It would be almost impossible to expect the Android API developers to include a pre-packaged set of attributes for every possible color/border combination, but there is always a solution!
Unfortunately,as you mentioned, the solution does reside in creating your own custom XML file which can often be intimidating until you get the hang of it. Once you do, you too will marvel at the flexibility it allows.
Specifically for your situation, there are two options...
1) Create a custom XML border drawable.
2)under your buttons background property set your new custom border drawable
3)then also set the ripple effect under your buttons xml properties by adding:
android:foreground="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
----OR----
A more complex way is to make a drawable like the one below. This will add the "ripple" button effect as well as a custom shadow, button color, and border color!
"For anybody reading this later that may be less experienced)
1)In your project view go to res/drawable
2)right click the folder itself and select new/drawable resource file
3)Enter a file name my_ripple_button.xml(the root doesn't really matter because you wil replace it with the below code)
4)Click on the text tab if you aren't already there
5)select all text and basically replace with the following: (creating a custom color border is basically the same steps)
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/colorPrimaryDark">
<item android:id="#android:id/ripple">
<shape android:shape="rectangle">
<solid android:color="#color/colorPrimaryDark" />
<corners android:radius="#dimen/button_radius_large" />
</shape>
</item>
<item android:id="#android:id/background">
<shape android:shape="rectangle">
<gradient
android:angle="90"
android:endColor="#color/colorPrimaryLight"
android:startColor="#color/colorPrimary"
android:type="linear" />
<corners android:radius="#dimen/button_radius_large" />
</shape>
</item>
</ripple>

Related

Android button border stay deafault after adding drawable file

I'm working on a project in android studio and I'm trying to change the border to my button.
My default button when I just add it to my grid look like this:
After adding new XML file (called box_solid_border.XML) in the drawable file that looks like this:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<stroke
android:width="4dp"
android:color="#000000" />
</shape>
the result is that it's creating the next shape that I can see:
and that exactly what I want to add to my button.
when I come back to my XML at the main file and add to my button the next line:
as you can see in line 226 I'm adding the background that I just created for this button to the button. and near the line, there is the exact border that I want.
but in the application, the button still stays the same as the default one with no border added to him.
Like this:
Does someone know the reason that the drawable file doesn't affect the button?
If I'm doing the same thing for a textView or something else its works perfectly fine, just the button looks like not affected by the drawable extension to him.
Thank you!
You need to add this attribute to your button:
app:backgroundTint="#null"
If it has both attributes android:background and app:backgroundTint(if you are using the default theme for your application, it has a default value), the color specified by app:backgroundTint will be cover on the shape of drawable.
For border to button try to edit box_solid_border.xml in drawable folder
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android">
<stroke
android:color="#color/black"
android:width="5dp"/>
<corners
android:radius="8dp"/>
<solid
android:color="#color/colorAccent"/>
</shape>
In layout xml file
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/box_solid_border"
android:text="Button"
android:textColor="#fff"
android:textSize="30sp" />

How to change the background color of EditText without removing the standard bottom border

After the call of EditText.setBackgroundColor(Color.RED) I see only a red rectangle with text inside it, but I want to change only the text background and to keep the standard bottom border which is grey when the field has no focus and blue if it has focus. Can I do it programmatically?
I want to change the text background to red if the input is invalid and to transparent if it is valid.
I think the best way is to work with drawable/shape.xml as background and upon logic code situation call EditText.setBackground(some_other_shape.xml). Here is an example for shape file xml demonstrating how to use:
Border color ("stroke"): In this example some custom color from colors.xml
Fill color ("solid"): In this example Android default transparent color
Even image icon inside
<!--Example for custom shape file xml design-->
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#mipmap/icon_image" />
<item>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#android:color/transparent" />
<stroke android:width="1dp" android:color="#color/orange_primary" />
</shape>
</item>
</layer-list>
So just prepare several shapes for each situation you need. Another approach is to work with layout params etc. but I think this one is faster and gives more control for custom design in easy to understand code.

Add Stroke to Top of Holo Button Without using solid in a drawable

I am trying to add a stroke to the top of a Holo button, my application allows theme change from Holo --> Holo.Light. Every piece of information I have found relates to providing a solid in a custom drawable. Is there a way to keep all the holo themed buttons intact and just add a stroke to the top of particular buttons?
Basically I want to keep the colors Holo/Light have but just add a stroke at the top.
Sample:
Tried drawable
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<corners android:radius="6dp" />
<solid android:colorBackground="#00000000" />
<stroke android:width="2px" android:color="#050875">
</stroke>
</shape>
This when applied as a background overrides the Holo/Light colors to transparent background.
What you should do, is create a drawable (with a colored stroke), like you described. You can then make the regulars solid color transparent color (#00000000) and apply it as a background to the view component you wish to style.

Why does assigning a color to the background of my ListView element not cover the entire ListView background, while assigning a drawable does?

I have a ListView that sits on the left side of a tablet-size screen. My goal was to give it a solid background with a border on the right, then apply an overlapping background on the list element to break that border so that it appears to be a part of the view on the right.
The ListView Background
I achieved the right border using a <layer-list> drawable as suggested by Emile in another question:
rightborder.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#color/black" />
</shape>
</item>
<item android:right="2dp">
<shape android:shape="rectangle">
<solid android:color="#color/white" />
</shape>
</item>
</layer-list>
...and here's the ListView definition for good measure:
<ListView
android:id="#+id/msglist"
android:layout_width="300dp"
android:layout_height="match_parent"
android:divider="#color/black"
android:dividerHeight="1dp"
android:background="#drawable/rightborder"
android:paddingRight="0dip">
</ListView>
<!-- I added the android:paddingRight after reading something
about shape drawables and padding, don't think it actually
did anything. -->
Attempting to override it with a color
In order to achieve the desired effect, I placed the following in the getView function of my adapter:
//If it's selected, highlight the background
if(position == mSelectedIndex)
convertView.setBackgroundColor(R.color.light_gray);
else
convertView.setBackgroundResource(0);
However, using this method, the black border of the ListView's drawable remained visible, and only the white part of the background was replaced by gray. Here's a screen capture:
Fixing it with a drawable
On a hunch, I replaced the color I was assigning with a shape drawable:
selectedmessage.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle"
xmlns:android="http://schemas.android.com/apk/res/android" >
<solid android:color="#color/light_gray" />
</shape>
getView snippet:
//If it's selected, highlight the background
if(position == mSelectedIndex)
convertView.setBackgroundResource(R.drawable.selectedmessage);
else
convertView.setBackgroundResource(0);
This achieves the desired result, as shown below:
The question:
Why does assigning a rectangle as the background for my ListView element cover the entire view, while assigning the color allows the black border to show through? I'm happy it's working, but I'd like to know why Android is rendering the view this way so I can learn more about how Android renders Views.
Other notes:
I'm running the project in the stock Android 3.2 emulator, if that makes any
difference.
One clue may be that the light_gray color background seems to render darker than the light_gray shape resource.
I doubt it makes a difference, but light_gray is:
<color name="light_gray">#FFCCCCCC</color>
You can't do this:
convertView.setBackgroundColor(R.color.light_gray);
setBackgroundColor does not take a resource id : http://developer.android.com/reference/android/view/View.html#setBackgroundColor(int)
So your getting some incidental behaviour that isn't doing what your expecting.
You would have to do:
convertView.setBackgroundColor(getResources().getColor(R.color.light_gray);
http://developer.android.com/reference/android/content/res/Resources.html#getColor(int)

Complex custom button states in Android

in my current project I'm building an App with API 10 which should look like an ICS App.
Since my GUI is not very complex I can build this all manually, but I have some problems with button states.
I googled a lot and found nothing that would work for me so I would appreciate any help ;)
I designed an action bar with google ICS stock icons. When for example someone touches the search-loupe-icon, which has an 8dp padding around it, it's background color should change to a defined highlight-color-value.
So now you would suggest probably a selector drawable. But my case is: I have an icon-drawable which has an background-color, which I want to change. I dont want to change the icon, so since I cant change the backgroundcolor from a selector-xml this doesn't work.
(I thought I can setup multiple drawable-xml with my icon static bg colors so that I could refer with one selector to those different colored icons, but since a shape-drawable-xml cannot have a source and an bitmap-drawable-xml cannot have a background color, this is no sollution.)
If I try to change the background color in my onclick-listener (also tried onTouch) with:
ImageButton searchIcon = (ImageButton) findViewById(R.id.upper_actionbar_icon_search);
searchIcon.setBackgroundColor(R.color.android_ics_blue_light);
The Icon gets a dark grey bg color. This is also true for any other color altough nothing lies on top of the ImageButton. I also tried an ImageView.
So could someone explain to my please how the hell I can define a highlighted bg color-image without any hacks (default-gone image that lies above the icon and is set visible onclick).
Thanks so much!!
Okay the solution is simple.
Write yourself a drawable selector which looks like this:
<?xml version="1.0" encoding="utf-8"?>
<item android:state_selected="true">
<shape android:shape="rectangle">
<solid android:color="#color/android_ics_blue_light"/>
</shape>
</item>
<item android:state_pressed="true">
<shape android:shape="rectangle">
<solid android:color="#color/android_ics_blue_light"/>
</shape>
</item>
<item>
<shape android:shape="rectangle">
<solid android:color="#color/light_grey"/>
</shape>
</item>
Within your ImageButton code define your icon as src and your new drawable as background, like this:
<ImageButton
<!-- ... -->
android:src="#drawable/icon_search"
android:background="#drawable/actionbar_ontouch"
/>
Works like a charm!

Categories

Resources