I am using a split ActionBar to display some simple media controls. See Below:
I used MenuItem.setActionView to override the default view for the Fast Forward and Rewind buttons because I need to detect when the user initially touches the control (to start rewinding) and subsequently releases the control (to finish rewinding). See code below:
ImageView rewindButton = new ImageView(getBaseContext());
rewindButton.setId(rewindViewID);
rewindButton.setClickable(true);
rewindButton.setImageResource(R.drawable.ic_action_rewind);
rewindButton.setOnTouchListener(forwardBackwardListener);
MenuItem rewindMenu = menu.findItem(R.id.menu_rewind);
rewindMenu.setActionView(rewindButton);
return true;
This is all working well for me but has had an unintended side effect. When I touch the fast forward or rewind button I do not get the default blue background (as shown on the skip backward control above). It displays no background at all. I tried setting the background in the onTouch handler but the background does not fill the height of the ActionBar in the same way as the default one (see example image below), it seems like there is some padding or margin in place, but I don't know how to remove it.
I have tried the following with no luck:
Setting the height of the ImageView Manually to try to fill the ActionBar
Returning True or False from the onTouch Handler
Does anyone know how I might resolve this?
I came up with a workaround which was to set the background of all the items to a small radial gradient when the item is selected. The gradient is still cut off a little but it is hardly noticeable. It makes the custom and regular buttons look almost the same.
First I created the radial gradient in a file called res/drawable/radialbackground.xml . Notice the end color is transparent, this is important to fade the gradient into nothing so it doesn't fill the whole rectangle.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<gradient
android:centerX="0.5"
android:centerY="0.5"
android:endColor="#00FFFFFF"
android:gradientRadius="35"
android:startColor="#color/Gray"
android:type="radial"
/>
</shape>
Then I created a StateListDrawable called res/drawable/actionitembackground.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:exitFadeDuration="#android:integer/config_mediumAnimTime" >
<item android:state_pressed="true" android:drawable="#drawable/radialbackground" />
<item android:drawable="#android:color/transparent" />
</selector>
Then I assigned that statelistdrawable to the backgrounds of my custom ActionViews :
rewindButton.setBackgroundResource(R.drawable.actionitembackground);
Then I altered the style for the actionbar to include this new radial fill for the regular action bar items.
So, in values/styles.xml I added:
<style name="Theme.MyTheme" parent="Theme.Sherlock.Light">
<item name="android:selectableItemBackground">#drawable/actionitembackground</item>
<item name="selectableItemBackground">#drawable/actionitembackground</item>
</style>
In my case, the base style was Theme.Sherlock.Light but you would replace that with whatever style you wanted to amend.
Then I set that style as the style for my application in AndroidManifest.xml
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/Theme.MyTheme"
android:uiOptions="splitActionBarWhenNarrow" >
This seemed easier than digging through trying to debug why the background is cut off. Perhaps I will spend more time on it another day.
I had exactly the same problem, but with a spinner on action bar,
you need to set de minHeight of yout view to actionBar height:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/drop_down"
android:minHeight="?android:attr/actionBarSize"
>
<Spinner
android:id="#+id/category_spinner"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/default_selector"
android:minHeight="?android:attr/actionBarSize"
android:gravity="center_vertical|right"
android:paddingRight="5dp"
/>
Related
I'm porting my app to Chrome OS and there are a few places in the app where arrow key navigation works, but the current focused element is not highlighted in any way. I've found that whenever I set a background color for an element like
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
...
android:background="#color/white" >
...
</LinearLayout>
then the default highlighting of the focused element will not show. Removing this will show the default background (which is not always the same as what I want).
Also, in cases where I use a selector in a ListView, the background is in front of the intended highlighting drawable (which can be seen if the color is somewhat transparent).
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:exitFadeDuration="#android:integer/config_mediumAnimTime" >
<item android:state_pressed="false" android:state_focused="true" android:drawable="#drawable/list_focused" />
<item android:state_pressed="true" android:drawable="#drawable/list_pressed" />
<item android:drawable="#color/white" />
</selector>
This is even more strange since I was under the (possibly incorrect) impression that selectors will only pick one of the items.
I can't post too much code since this is work code, but this is happening throughout the app wherever there's a list.
If you have a selector defined for the views in your ListView, set the drawSelectorOnTop property to true on your ListView, as per the docs.
I have a AppCompatButton defined in a XML layout, and I have set a theme for it like this:
android:theme="#style/CustomAccentOverlay"
And I have set:
android:stateListAnimator="#null"
to remove the shadow. I have two problems with this.
The height of the button is deducted the height of the shadow, even though the shadow is not shown. Should I remove the shadow in some other way, or how do I fix this?
The button has rounded corners, and I want the corners to be sharp. I can not set a background on the button, because I want to keep the standard ripple effect and that goes away if I set a background (at least I don't know how to keep it if I set a background). I have tried setting
<item name="android:bottomLeftRadius">0dp</item>
and all the other corners to the CustomAccentOverlay theme and also its corresponding style, but it does not work. How can I set the corner radius to zero on my button?
Thank you
Søren
Use the following code for the Button.
<android.support.v7.widget.AppCompatButton
android:layout_width="200dp"
android:layout_height="200dp"
android:text="Button"
android:stateListAnimator="#null"
android:elevation="0dp"
android:background="#android:color/darker_gray"
android:foreground="?attr/selectableItemBackground"
/>
I will explain the attributes.
android:elevation="0dp" and android:stateListAnimator="#null". No shadow for the button.
android:background . Set the desired color as background. It removes the rounded corners.
android:foreground="?attr/selectableItemBackground" . It gives the ripple effect when the button is pressed.
Update 1:
It seems like android:foreground attribute for View works from API 23. For below APIs, create a drawable with ripple in drawable-v21 folder and set it as background to the button,
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:ignore="NewApi"
android:color="#color/ripple_color">
<item android:drawable="#color/normal_state_button_background_color"/>
</ripple>
For pre Lollipop versions, create a drawable with selector in drawable folder with the same name.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/pressed_color"
android:state_pressed="true" />
<item android:drawable="#drawable/focused_color"
android:state_focused="true" />
<item android:drawable="#drawable/normal_color" />
</selector>
First question:How to remove shadow of a button?
Here is the answer:
Just add this attribute to your button
android:stateListAnimator="#null"
Second question: How to make the corner of button sharp without losing the standard ripple effect.
Here is the answer: But first you have to make two drawble file with same name but one for below api 21 and one for api > 21 because the ripple is only available only api > 21.So now I am showing how to create that.Read the following text carefully
Right click on the drawble folder and choose new and "Drawble resource file" and hit next then name the drawble whatever you like and press ok.Then again right click on the drawble folder and choose new and "Drawble resource file" and hit next and name the drawble exactly what you named the previous drawble folder but this time at the bottom you can see a section called "available qualifiers".Go to this section and at the very bottom you can see "Version",click it and then you can see a arrow icon at the right,click it then in the "Platform api level" add 21 and then press ok.And now if you expand drawble folder you can see two file of your created drawble file.Once for api that is below 21 and once for upper 21.Open drawble file that you have created and make sure you open that have "(v21)" at the last.Now delete everything from there and add the following code
<?xml version="1.0" encoding="utf-8"?>
<ripple android:color="?attr/colorControlHighlight" xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<corners android:radius="0dp"/>
<solid android:color="#D6D7D7"/>
</shape>
</item>
</ripple>
And add this attribute to your button
android:background="#drawable/youdrawblefilethatyouhavecreated"
And now if you run your application you can see that there is no shadow and your button has sharp corner and if you click the ripple shows up.
Lastly,your button look something like this
<android.support.v7.widget.AppCompatButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button 1"
android:background="#drawable/yourcreatddrawblefile"
android:stateListAnimator="#null"/>
Hope this help!
It really sounds like you want to use a clickable TextView rather than a Button. TextView by default will not have shadow and has sharp corners and you can attach a click listener to it. Remember, Button is just a fancy TextView with a lot of visual add-ons to it, and it sounds like you want to remove a lot of it.
If you want to keep the ripple on the TextView and define your own background, set android:foreground="?attr/selectableItemBackground"
EDIT: Even though the other answer was marked accepted, I would still argue that the OP should use a TextView with a click listener and applying the ripple effects to that than using a Button. Clickable TextViews in this manner are exactly how the Google I/O app implements all of their flat buttons that meet Material Design spec.
Use this code
<android.support.v7.widget.AppCompatButton
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#color/colorAccent"
android:text="#string/button" />
So my graphics artist came to me with a really cool layout for controls on our new app. The problem is getting these images laid out since most views in android are rectangular. See image for what I have to work with.
Any idea how to layout these buttons so they shape around each other if that makes sense?
If the problem is the layout, you can draw the buttons and save it as png. You can layout your app by RelevantLayout . And use the "selector" to change the button image when user press an so on.
selector example: "drawable/selector1.xml"
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:state_pressed="true" android:drawable="#drawable/buttonClicked" /> <!-- focused and pressed-->
<item android:state_pressed="true" android:drawable="#drawable/buttonClicked" /> <!-- pressed -->
<item android:drawable="#drawable/button" /> <!-- default -->
</selector>
use it like this:
android:background="#drawable/selector1"
the Views in android are rectangular, that is correct. The only workaround I see here: use multiple "invisible" Buttons (alpha set to 0). You can position them around the screen and assign the same action to some of them. Of course you'll need to implement the OnClickListener and use switch-case.
I have an ImageButton with a background image that has some transparency. By default, the button gets a grey background where the transparency pixels are - due to the Holo.Light theme. I tried setting the background color of the button to transparent via the setBackgroundColor(Color.TRANSPARENT) method. That works just fine and does what I need except now my button no longer has the light blue color when focused/pressed and looks rather flat (no borders around it, so it looks like an image).
I googled and saw that you can assign selectors as explained here but that would mean that I have to specify an image per button state and I don't want to do that. I want to inherit the focuses/pressed colors from the theme but overwrite the normal button background (when not pressed/focused) to transparent instead of grey. How can I achieve that?? Please provide a working example as I have tried many different combinations with no success.
Edit
Thank you all for helping. I figured out how to make this work without having to recreate the same image with the focused and pressed states for each button!
Here is my solution:
My button is defined as:
<ImageButton
android:id="#+id/ImageButton05"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="#drawable/button" />
And my background XML file (titled button.xml) is defined as follows:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<layer-list>
<item android:drawable="#drawable/btn_default_pressed_holo_light"></item>
<item android:drawable="#drawable/network_wifi"></item>
</layer-list>
</item>
<item android:state_focused="true">
<layer-list>
<item android:drawable="#drawable/btn_default_focused_holo_light"></item>
<item android:drawable="#drawable/network_wifi"></item>
</layer-list>
</item>
<item android:state_hovered="true">
<layer-list>
<item android:drawable="#drawable/btn_default_focused_holo_light"></item>
<item android:drawable="#drawable/network_wifi"></item>
</layer-list>
</item>
<item>
<layer-list>
<item android:drawable="#drawable/btn_default_normal_holo_light"></item>
<item android:drawable="#drawable/network_wifi"></item>
</layer-list>
</item>
</selector>
You can put something into an xml file, for example, custom_button.xml and then set background="#drawable/custom_button" in the button view.
Please refer to this link as there is an xml example: Standard Android Button with a different color
I used it in my code and it worked just the way I wanted.
Reference:
Standard Android Button with a different color
Edited:
If you would rather use
Maybe you should try to set a border.
For example (Reference: Android - border for button ):
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient android:startColor="#FFFFFF"
android:endColor="#00FF00"
android:angle="270" />
<corners android:radius="3dp" />
<stroke android:width="5px" android:color="#000000" />
</shape>
OR,
You could try to set the style/theme for the button. (But it would be in a separate file)
The style/theme contains the color attributes for various states of button such as focused / enabled / disabled/ etc.
For setting background color/image and having click highlight effect,
Here is an example (Reference: How to programmatically setting style attribute in a view)
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="true"
android:drawable="#drawable/btn_pressed" />
<item
android:state_pressed="false"
android:drawable="#drawable/btn_normal" />
</selector>
You can then apply this selector to a Button by setting the property android:background="#drawable/my_button".
I want to inherit the focuses/pressed colors from the theme but overwrite the normal button background (when not pressed/focused) to transparent instead of grey. How can I achieve that??
AFAIK you can't because the focus/pressed colors are built in to the same image resources that contain the grey background.
If you want to keep the system focus/pressed but remove the background you'll have to grab a copy of the image resources (which can be found in your SDK at /sdkroot/platforms/[version]/data/res/drawable-hdpi replace [version] with whatever api level you are after. And if needbe replace hdpi with another density) and edit out the grey button from them with a photo editor. Then make a selector that references your modified images and set that as the background for your button.
EDIT:
Here are the default holo button images for focused and pressed
You can use ImageView instead of ImageButton to solve your problem. Please set the android:background property of the ImageView to the background color of the parent.
You can write this in your xml file:
android:background="#null"
It worked for me.
if u don't need the default gray background and u need your ImageButton seems like an icon without no backgrounds just use android:background attribute and set it to
#android:color/transparent**
<ImageButton
android:id="#+id/ImageButton05"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="#android:color/transparent"
android:background="#drawable/button" />
hope that help anybody
WARNING: The XML in this question is wrong, read the answer before you confuse yourself!
I have been banging my head on the wall for a while now. The following posts have shed light on the subject, but failed to solve my issue: Android ListView State List not showing default item background and ListView item background via custom selector
The proper nine-patch background shows perfectly when I select the list item, but I can not get the default nine-patch background to show initially. It seems to me that I need to set the default item background somehow, but I can't figure out how to do so.
List View:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/shopListHeader"
/>
<ListView
android:id="#+id/shopList"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:dividerHeight="0px"
android:divider="#FFFFFFFF"
android:listSelector="#drawable/shop_list_selector"
/>
</LinearLayout>
Selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:visible="true">
<!-- the list items are enabled and being pressed -->
<item
android:state_pressed="true"
android:drawable="#drawable/shop_list_item_pressed" />
<item
android:state_selected="true"
android:textColor="#FFFFFFFF" />
</selector>
Background:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:visible="true">
<item
android:state_selected="true"
android:drawable="#android:color/transparent" />
<item
android:drawable="#drawable/shop_list_item" />
</selector>
As you can see, I have dumbed down the examples from the references.
You may also notice that the Background selector isn't being referenced anywhere. I started tossing it in random places (if the app compiled the addition either had no effect or cause a forced close)
I have also made an attempt to stop the color of the text from changing to black and grey when an item is selected but not pressed (can be done by scrolling through the list). Since my background will be black in the center, the text becomes partially invisible when selected. That addition (the last item node in the Selector) does nothing, as far as I can tell.
Does anyone have any thoughts on getting this ridiculously time consuming functionality working?
I was gonna delete this thread, but I can't so I'll see if I can't use this as an example of what not to do :)
First, in the ListView XML: android:listSelector="#drawable/shop_list_selector"
Don't do that!
What I was trying to do here was set the background of the list items and the android:background property didn't work. You may have noticed that the item XML is missing, and that is because it was missing from my head! (I never touched it over the countless hours I was hammering away at this 'issue') So the line android:background="#drawable/shop_list_selector" goes in the item's properties and everything is groovy. (Remember the XML above is very wrong so don't use it!)
...Well except that it doesn't look as good in real life as it did in my head :(
Back to the drawing board!!!
You havent defined a "normal" state, see this example
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/blue"
android:state_pressed="true" />
<item android:color="#color/red"
android:state_selected="true" />
<item android:color="#color/white" />
</selector>
in here white is the "normal" state, in here you can find some documentation about it.
I hope this helps