I'd like to remove the blue color (I'm testing my app with Holo) appearing when I click on a Spinner.
My code :
ArrayAdapter<String> array_adapter = new ArrayAdapter<String> (getActivity(),
R.layout.spinner_item, string_array);
array_adapter.setDropDownViewResource(R.layout.spinner_item);
Spinner spinner = (Spinner) getView().findViewById(R.id.spinner);
spinner.setAdapter(array_adapter);
spinner_item.xml
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/spinner_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAllCaps="true"
android:background="#drawable/item"
style="#style/EquidiaTheme.MySpinner" />
and item.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#android:color/transparent" />
<item android:state_selected="true" android:drawable="#android:color/transparent" />
<item android:drawable="#android:color/transparent" />
</selector>
This doesn't work. Any idea?
Customize android:spinnerDropDownItemStyle
Styling ActionBar dropdown menu
I was able to get rid the blue rectangle on item when I select it when I done this:
First I declare color that I want to use in values.xml:
<resources>
<drawable name="red_color">#ff0000</drawable>
<drawable name="blue_color">#0000ff</drawable>
<drawable name="green_color">#00ff00</drawable>
<drawable name="transparent_color">#00000000</drawable>
</resources>
Than I define custom style in Styles.xml
<resources>
<style name="Theme.Spinner" parent="android:Theme.Holo">
<item name="android:attr/listChoiceBackgroundIndicator">#drawable/transparent_color</item>
</style>
</resources>
in the style I was able to use only colors defined in resources ( Setting color like: #android:color/XXX or #XXX directly in style didn't work)
After all I aplly the them on Activity. I use Xamarin so may code is:
[Activity( Label = "TestLayouts", MainLauncher = true, Icon = "#drawable/icon", Theme="#style/Theme.Spinner")]
but for android it should be:
<activity android:theme="#style/Theme.Spinner">
I use this answer for reference:
Default selector background in Clickable Views
also to get rid the blue rectangle on spinner itself use:
<Spinner
android:background="#null"
You need to use both to completly remove blue rectable.
Also maybe this attributes in style may help you:
<item name="android:attr/colorPressedHighlight">#FF0000</item>
<item name="android:attr/colorLongPressedHighlight">#FF0000</item>
<item name="android:attr/listChoiceIndicatorSingle">#drawable/red_color</item>
A solution without theme. Ideal if you only got a few spinner.
create a drawable (xml) with state (https://developer.android.com/guide/topics/resources/drawable-resource.html#StateList)
use the SAME image for the state PRESSED and NORMAL
then use it as background :
mySpinner.setBackgroundResource(R.drawable.my_spinner_state_drawable)
extra tips:
you can use system drawable (image) from the system resource: like "#android: drawable/btn_dropdown_normal". It is easier to maintain and give a more native look and feel.
ref http://androiddrawables.com/Buttons.html
Related
I've seen some SO questions and they gave some possible methods to achieve what I want. For example:
Use colorControlHighlight attribute in styles.xml.
Here is my styles-v21.xml:
<style name="SelectableItemBackground">
<item name="android:colorControlHighlight">#5677FC</item>
<item name="android:background">?attr/selectableItemBackground</item>
</style>
And my widget:
<TextView
android:id="#+id/tv_take_photo_as_bt"
android:layout_width="280dp"
android:layout_height="48dp"
android:text="#string/act_take_photo"
style="#style/SelectableItemBackground"/>
And it doesn't work. I also tried to add parent="Theme.AppCompat to "SelectableItemBackground" style, or change to colorControlHighlight(no android: prefix)", or change to ?android:attr/selectableItemBackground, neither is useful.
Use backgroundTint attribute in layout.
So I add android:backgroundTint="#5677FC" to my TextView. Still useless. Then I tried to change android:backgroundTintMode to src_in and src_atop, and they never make a difference.
So, how can I change ripple color when I use ?attr/selectableItemBackground as background. I only focus on Lollipop and above. Thank you in advance!
Finally I find the solution: instead of using android:colorControlHighlight directly in theme SelectableItemBackground, I should write another style:
<style name="SelectableItemTheme">
<item name="colorControlHighlight">#color/ripple_color</item>
</style>
Then:
<style name="SelectableItemBackground">
<item name="android:theme">#style/SelectableItemTheme</item>
<item name="android:background">?attr/selectableItemBackground</item>
</style>
Finally add style="#style/SelectableItemBackground" to View in layout.xml.
UPDATED ON 2016/8/26
After N's release, I found that sometimes we cannot use this method to set ripple color for some kind of View(for example, the CardView). Now I highly recommend developers using RippleDrawable, which can also be declared in xml. Here is an example:
I want to show a ripple effect when user touches/clicks a CardView above API21, and of course there should be another kind of feedback before Lollipop. So I should write:
<android.support.v7.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:foreground="#drawable/selectable_item_background"/>
and selectable_item_background in drawable folder:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false" android:drawable="#android:color/transparent" />
<item android:drawable="#color/color_clicked" />
</selector>
selectable_item_background in drawable-v21 folder:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/ripple_black" />
</selector>
finally, the ripple_black in drawable(or drawable-v21) folder:
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:color="#color/color_clicked"
tools:ignore="NewApi" /> <!--you can remove this line if it's in v21 folder-->
That's it. For other views, maybe you should use android:background="#drawable/selectable_item_background". Don't forget to set an OnClickListener, OnTouchListener or something like those for them, otherwise ripple won't show.
Ripple effect on pre- and Lollipop+ devices
harrane and Liuting are right. The accepted answer is not the best way.
Let me show in code how to change ripple color for pre-Lollipop versions and higher
Your AppTheme should inherit from any AppCompat theme and contain colorControlHighlight attribute (without 'android:' prefix)
<!-- Application theme. -->
<style name="AppTheme" parent="#style/Theme.AppCompat.Light.NoActionBar">
<item name="colorControlHighlight">#40ffffff</item>
</style>
Your view should contain clickable="true" (or should have a click listener set programmatically) and background should be "?attr/selectableItemBackgroundBorderless" or "?attr/selectableItemBackground" :
<LinearLayout
...
android:clickable="true"
android:background="?attr/selectableItemBackgroundBorderless"/>
Note: that if your parent view has white background you won't see ripple effect since it's white. Change colorControlHighlight value for a different color
Also, if you want different ripple colors on different activities you can set personal theme for each activity in Manifest file, for example:
<activity
android:name="com.myapp.GalleryActivity"
android:theme="#style/RedRippleTheme"
/>
Different ripple colors for different fragments in the same activity?
You can change attributes of Activity Theme for each fragment in runtime. Just overwrite them before fragment was inflated with your custom style and apply to a current Theme:
in values/styles.xml
<style name="colorControlHighlight_blue">
<item name="colorControlHighlight">#color/main_blue_alpha26</item>
</style>
Then, in your fragment before inflation in onCreateView():
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
getContext().getTheme().applyStyle(R.style.colorControlHighlight_blue, true); //blue ripple color
View view = inflater.inflate(R.layout.my_fragment_layout, container, false);
return view;
}
This style will work only for this fragment
Different ripple color for different Views? (Lollipop +)
You can change the ripple color for each view seperately using
colorControlHighlight attribute, it doesn't work if you apply them to a view directly:
<TextView
...
colorControlHighlight="#40ffffff"/> <!-- DOESN'T WORK -->
you should apply it as a theme:
<TextView
...
android:theme="#style/colorControlHighlight_blue"/>
P.S. Also, sometimes this approach helps if you have unknown issues with ripple and you can't figure it out.
In my case, I used 3rd party sliding lib which messed up ripple effects for the entire layout and adding explicitly this theme to all clickable views worked out for me.
It's showing ripple effect with color on API +21, and simple gray background on press for API -21.
Add this style:
<style name="AppTheme.MyRipple">
<item name="colorControlHighlight">#color/your_color</item>
<item name="android:background">?selectableItemBackgroundBorderless</item>
</style>
And set it to the view:
<Button
...
android:theme="#style/AppTheme.MyRipple" />
Use the below steps:
1. Make changes to button view in your layout.xml
2. Add new styles in styles.xml
your_layout.xml
<Button
android:id="#+id/setup_submit_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="#string/action_sign_in"
android:textStyle="bold"
android:background="#color/colorPrimary"
android:textColor="#color/white"
style="#style/SelectableItemBackground"
android:foreground="?android:attr/selectableItemBackground"/>
-The style attribute calls the style that we created.
-Foreground attribute calls the andorid's default selectable attribute.
styles.xml
<style name="SelectableItemTheme">
<item name="colorControlHighlight">#color/white</item>
</style>
<style name="SelectableItemBackground">
<item name="android:theme">#style/SelectableItemTheme</item>
<item name="android:background">?attr/selectableItemBackground</item>
</style>
The accepted answer is wrong.
The correct way to use is what Liuting mentioned in the comment.
Use colorControlHighlight instead of android:colorControlHighlight for changing the default colorControlHighlight from AppCompat
* Please refer to http://android-developers.blogspot.co.uk/2014/10/appcompat-v21-material-design-for-pre.html in the Theming section *
This code works for me to create a ripple:
public static void setRippleDrawable(View view, int normalColor, int touchColor) {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
RippleDrawable rippleDrawable = new RippleDrawable(ColorStateList.valueOf(touchColor), view.getBackground(), null);
view.setBackground(rippleDrawable);
} else {
StateListDrawable stateListDrawable = new StateListDrawable();
stateListDrawable.addState(new int[]{android.R.attr.state_pressed}, new ColorDrawable(touchColor));
stateListDrawable.addState(new int[]{android.R.attr.state_focused}, new ColorDrawable(touchColor));
stateListDrawable.addState(new int[]{}, new ColorDrawable(normalColor));
view.setBackground(stateListDrawable);
}
} catch (Exception e) {
Log.e(LOG_TAG, "" + e);
}
}
I did not found any way to modify the selectableItemBackground attribute.
That's why I did it like above.
In dark black theme(Or any other) app try to use like below
first create ripple_effect.xml in drawable folder and add code like
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#f5f5f5">
<item android:id="#android:id/mask">
<shape android:shape="rectangle">
<solid android:color="#f5f5f5" />
</shape>
</item>
</ripple>
then set background to your Any view like Linear layout, Button, TextView etc.
<TextView
android:id="#+id/tvApply"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/ripple_effect"
android:clickable="true"
android:text="APPLY"
android:textColor="#FFFFFF"
android:gravity="center"
android:textSize="#dimen/_8sdp"
android:padding="#dimen/_8sdp"
android:focusable="true" />
Use the foreground attribute as selectableItemBackground
and background attribute as the color you want.
android:foreground="?attr/selectableItemBackground"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="#color/white"
I have been using the new MaterialButton class. I want different colors on the button when the user clicks the button.
I have been using selector drawables for this purpose since the very beginning, however it doesn't appear to be working on MaterialButton.
<com.google.android.material.button.MaterialButton
android:layout_width="0dp"
android:text="#string/login"
style="#style/Widget.Mohre.Button"
android:layout_height="wrap_content"
app:cornerRadius="#dimen/card_corner_radius"
android:padding="#dimen/unit_large"
android:id="#+id/loginBtn"/>
My Widget.Mohre.Button style
#color/textColorWhite
#drawable/mohre_button_selector
#style/TextAppearance.Button
#animator/button_state_list_anim
My selector drawable
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/mohre_button_pressed" android:state_pressed="true" />
<item android:drawable="#drawable/mohre_button_selected" android:state_enabled="false" android:state_pressed="false" />
<item android:drawable="#drawable/mohre_button_normal" />
My individual drawables are just rectangle shapes with different colors like these
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="30dp"></corners>
<solid android:color="#3a516a"></solid>
</shape>
The button doesn't take on the colors at all from the selector drawable. It just shows the default accent color of the application
With the normal way (setting the selector drawable as background of the button), it won't work as expected if you are using Theme.MaterialComponents.
You can use Theme.AppCompat.DayNight.NoActionBar as an alternative, but if you don't want to use that theme, then simply use:
<androidx.appcompat.widget.AppCompatButton
................/>
You will get the same result as it was working with the Appcompat theme even if you are using latest Material themes!
as explained in this medium post https://medium.com/over-engineering/hands-on-with-material-components-for-android-buttons-76fa1a92ec0a we can use ColorStateList to change color or background of Button.
For me working solution for now was to set backgroundTint to null and backgroundTintMode to add like this:
<style name="Button.XYZ" parent="Button">
<item name="shapeAppearance">?attr/shapeAppearanceLargeComponent</item>
<item name="drawableTint">#color/ColorXYZ</item>
<!-- background drawable -->
<item name="backgroundTint">#null</item>
<item name="backgroundTintMode">add</item>
<!-- background drawable -->
<item name="android:background">#drawable/XYZ</item>
<!-- Color drawable -->
<item name="android:textColor">#color/XYZ</item>
</style>
And also using the style in xml not in theme
If you want a button that has a custom background (to apply <selector> e.g), but your theme is set up to use Theme.MaterialComponents (which is nowadays, 2021), you could switch the XML element in the layout to be <android.widget.Button> instead of <Button>. This should cause the Material Components for Android to ignore that element, and you can manipulate this button normally with respect to XML attributes.
I want to color my button that is defined in a fragment. I created new style (which I use as a theme in the button) and defined "colorAccent" for enabled state, "colorButtonNormal" for disabled and parent of this style is "Widget.AppCompat.Button". I want it to be coloured exactly as it is written in colorButtonNormal when button is disabled.
<style name="Material.Button.Primary" parent="#style/Widget.AppCompat.Button">
<item name="android:colorButtonNormal">#color/color_disabled</item>
<item name="colorAccent">#color/color_primary</item>
</style>
<Button
style="#style/Widget.AppCompat.Button.Colored"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/button_text"
android:textAppearance="#style/AppTheme.Text"
android:theme="#style/Material.Button.Primary" />
When the button is enabled it has correct color from colorAccent. When user clicks on it, it becomes disabled and should be gray (#b2b2b2) but it becomes a little bit lighter (#E7E7E7). It seems like it takes color that I defined and mixes with white color.
I tried to change style's parent and did some changes in style and button's attributes as it is written in some guides from the internet but nothing worked. My current solution is to set colorButtonNormal to #000000. When button is disabled, it becomes #B9B9B9.
Forgive me if I am wrong but as far I understand correctly, you want to achieve different colours for enabled/disabled states.
UPDATE
For keeping the material effect you can use styling with Widget.AppCompat.Button.Colored and create theme with specified colours:
<Button
.
.
.
style="#style/Widget.AppCompat.Button.Colored"
android:theme="#style/CustomButton"/>
And create theme, where colorButtonNormal is for disabled state
<style name="CustomButton" parent="Widget.AppCompat.Button.Colored">
<item name="colorButtonNormal">#color/color_disabled</item>
<item name="colorAccent">#color/color_enabled</item>
</style>
Old without material effect
You can try using selector like:
custom_button.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:drawable="#color/color_disabled" />
<item android:state_enabled="true" android:drawable="#color/color_enabled/>
</selector>
and then in your xml for button:
<Button
.
.
.
android:background="#drawable/custom_button" />
I've got in attrs.xml
<resources>
<!-- theme specific colors -->
<attr format="reference|color" name="foreground" />
<attr format="reference|color" name="background" />
</resources>
And then in theme.xml
<style name="MyTheme" parent="android:Theme.Black">
<item name="android:windowNoTitle">true</item>
<item name="foreground">#0000FF</item>
<item name="background">#00FF00</item>
</style>
I also created color selector named forground_to_background.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="?background"/> <!-- pressed -->
<item android:state_focused="true" android:color="?background"/> <!-- focused -->
<item android:color="?foreground"/> <!-- default -->
</selector>
Now I'd like to use it all together in TextView:
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#color/forground_to_background" />
Unfortunately it doesn't work. Instead of having nice green blue colors I've got only one color - red. TextView is always red. When I change TextView to use "?foreground" color will change. Also when I change in colors selector from "?xxxx" to hardcoded value as "#00f" color start to work.
Where is problem? What am I doing wrong?
Edit:
I believe it is duplicate of problem/bug Can a selector resource use a color defined in a style?
Edit2:
Moreover when I try use this TextView in ListView application crashes. It cannot parse XML.
You cannot reference ?attr/ when choosing colors for a selector. What you can do, if you want per-theme colors in your selector, is create multiple selectors which reference #color/ and #drawable/, and then have a "reference" attr which associates one of the selectors with the given style.
<attr name="forground_to_background" format="reference" />
You then have to set the text color like
android:textColor="?attr/forground_to_background"
I believe the text was always red because Android was interpreting the attr's integer value as a color (red), rather than using it as a lookup for what you actually wanted.
The reason why this happens is that I have different Context. While inflating Context is aware of my theme attrs, but to the ListView adapter I passed ApplicationContext that wasn't aware of those attrs. Now I don't know why it doesn't know about them ;)
Are you sure if you applying MyTheme to the activity or the textview?
Another thing you can try is that instead of using the "?" operator in your forground_to_background.xml, trying using "#" instead. see if that fixes your problem
I'm creating a spinner in my layout xml files and setting an string array to this spinner.
If I change the textstyle of the spinner the text is not affected by the changes.
I read in the googlegroups that a spinner has no text and therefore the textstyle can not be changed and I have to change the style of the textview that is shown in the spinner. But how can I do that. Preferably in my xml file.
As my predecessor specified, you can't do it on the main XML layout file where the Spinner component is.
And the answer above is nice, but if we want to use Google's best practices, like you know... to use styles for everything... you could do it in 3 'easy' steps as follows:
Step 1: You need an extra file under your layout folder with the look for the Spinner's items:
<?xml version="1.0" encoding="utf-8"?>
<TextView
android:id="#+id/textViewSpinnerItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/SpinnerTextViewItem"
xmlns:android="http://schemas.android.com/apk/res/android" />
Name this file: spinner_item_text.xml
Step 2: Then, on your Activity Class when you are filling the Spinner with an array of items:
adapter = new ArrayAdapter<CharSequence>(this, R.layout.spinner_item_text, items);
spinner.setAdapter(adapter);
Note that the R.layout.spinner_item_text resource is in your own R's file.
Step 3: Under your values folder, create or use (you might have one already) the file styles.xml. The style entry needed should look like this one:
<style name="SpinnerTextViewItem" parent="#android:style/Widget.TextView" >
<item name="android:textSize" >8dp</item>
<item name="android:textStyle" >bold</item>
</style>
And that's it!
So far it has been really, really handy to put all about text sizes, styles, colors, etc... on a styles.xml file so it's easy to maintain.
Via XML Only
As a follow-up to #Cyril REAL's excellent answer, here is a thorough implementation of how to style your Spinners just through XML if you're populating your Spinner via android:entries.
The above answers work if you're creating your Spinner via code but if you're setting your Spinner entries via XML, i.e. using android:entries, then you can adjust the text size and other attributes with the following two theme settings:
In your res/values/styles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppBaseTheme" parent="android:Theme.Holo">
</style>
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<!-- For the resting Spinner style -->
<item name="android:spinnerItemStyle">
#style/spinnerItemStyle
</item>
<!-- For each individual Spinner list item once clicked on -->
<item name="android:spinnerDropDownItemStyle">
#style/spinnerDropDownItemStyle
</item>
</style>
<style name="spinnerItemStyle">
<item name="android:padding">10dp</item>
<item name="android:textSize">20sp</item>
<item name="android:textColor">#FFFFFF</item>
</style>
<style name="spinnerDropDownItemStyle">
<item name="android:padding">20dp</item>
<item name="android:textSize">30sp</item>
<item name="android:textColor">#FFFFFF</item>
</style>
</resources>
When you create the Adapter that backs the Spinner you can set a layout for the spinner item.
spinner.setAdapter(new ArrayAdapter(this, R.id.some_text_view));
You can style some_text_view the way you want.
<TextView android:id="#+id/some_text_view" android:textStyle="bold" />
Actually you can customize spinner's text by xml.
In your own style, define a :
<item name="android:spinnerItemStyle">#style/yourStyleForSpinnerItem</item>
and define this style also :
<style name="yourStyleForSpinnerItem">
// Stuff you want for the item style.
</style>
When you instantiate the spinner's adapter in the java code, you can use the default android.R.layout.simple_spinner_item
If you don't want such workarounds, there's a simple way. Get the textview from the spinner and change its parameters:
TextView tv = (TextView) spin.getSelectedView();
tv.setTypeface(Typeface.DEFAULT_BOLD); //to make text bold
tv.setTypeface(Typeface.DEFAULT); //to make text normal
if you want just change background of popup View in spinner, call this method:
spinner.setPopupBackgroundResource(R.color.pa_md_white);