Is it possible to manipulate the style of a text field found in API 17 of android in API 8 ??
The text field in lower API's are very different in comparison with the higher API's. Is there any way to give a uniform look and feel for these components?
To use Android v8 EditText style, change the background of the editText:
android:background="#android:drawable/edit_text"
or use the whole style used in v8:
<style name="Widget.EditText">
<item name="android:focusable">true</item>
<item name="android:focusableInTouchMode">true</item>
<item name="android:clickable">true</item>
<item name="android:background">#android:drawable/edit_text</item>
<item name="android:textAppearance">?android:attr/textAppearanceMediumInverse</item>
<item name="android:textColor">#android:color/primary_text_light</item>
<item name="android:gravity">center_vertical</item>
</style>
Only the EditText? Or do you want every widget to look like pre holo widgets? If so, then setting this as your theme will help:
<application
[...]
android:theme="#android:style/Theme" >
[...]
</application>
However if you just want to have the EditText to be "un-holofied" you can do this:
<EditText
android:id="#+id/spinnermap"
style="#style/MyEditText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true" />
values/styles.xml:
<style name="MyEditText" parent="android:Widget.Spinner"></style>
and set your Theme to Holo(.Light) and Theme(.Light) for pre HC.
Or if you want to combine everything into one theme with everything except the EditText widget being holo, then you can do this:
values-v11/styles.xml: // v11 because pre HC themes already have the EditText style, you want.
<style name="MyTheme" parent="#android:style/Theme.Holo"
<item name="android:editTextStyle">#style/MyEditText></item>
</style>
Or you can use this:
https://github.com/Prototik/HoloEverywhere
if you want to have Holo on older devices (I mean that you can do it in the opposite way - change old controls to look line new ones). This library also works with ActionBar Sherlock.
Related
In an app of mine, I'm using the Theme.MaterialComponents.Light.NoActionBar as a base style. In this style, which I call AppTheme, I'm trying to override editTextStyle to provide a custom style for com.google.android.material.textfield.TextInputEditText (according to the source code, it uses R.attr.editTextStyle as a default style).
This is my current theme, related to the TIEditText and TILayout:
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
[ primary and secondary colors, OnColors, etc.]
<item name="editTextStyle">#style/AppTheme.TextInputEditText</item>
<item name="textInputStyle">#style/AppTheme.TextInputLayout</item>
[ Custom attribute for testing, defined in attrs.xml ]
<item name="textInputEditTextStyle">#style/AppTheme.TextInputEditText</item>
</style>
For some reason, even though I set editTextStyle, if I use it in code, it does not get applied:
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/tilFirstName"
style="?attr/textInputStyle"
android:hint="#string/label_firstname"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/firstName"
style="?attr/editTextStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:text="#={viewModel.firstName}" />
</com.google.android.material.textfield.TextInputLayout>
However if I replace the style of firstName with ?attr/textInputEditTextStyle, it works.
Why can't I override editTextStyle in the default theme? What the hell is going on?
Target SDK is 28, minSDK is 21, Material library version is 1.1.0-alpha06
Let's just move past the part where we all recognize that Android themes and styles are singularly the most absurd wasteland of hackery and guesswork ever devised by human beings.
This is an expansion on the previous answer. Same silly 'hack'. I was able to style the TextInputEditText by setting editTextStyle, but not where it intuitively belongs, but rather inside a custom materialThemeOverlay nested within the style defined for textInputStyle. Witness:
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- works fine -->
<item name="textInputStyle">#style/AppTheme.TextInputLayoutStyle</item>
<!-- should work fine, doesn't work, happily ignored -->
<!-- <item name="editTextStyle">#style/AppTheme.TextInputEditTextStyle</item> -->
</style>
<style name="AppTheme.TextInputLayoutStyle" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox">
<!-- other props (boxBackgroundMode, boxBackgroundColor, boxStrokeColor, etc) -->
<!-- can we set editTextStyle from here? Of course not! We should magically know we need a material theme overlay-->
<item name="materialThemeOverlay">#style/AppTheme.MaterialThemeOverlay</item>
</style>
<!-- style inception! a style, child of another style, whose only purpose is to refer to yet another style -->
<style name="AppTheme.MaterialThemeOverlay">
<item name="editTextStyle">#style/AppTheme.TextInputEditTextStyle</item>
</style>
<!-- finally, the style we SHOULD have been able to set from the theme -->
<style name="AppTheme.TextInputEditTextStyle" parent="#style/Widget.MaterialComponents.TextInputEditText.OutlinedBox">
<item name="android:textColor">#color/white</item>
</style>
All of the above ridiculousness and ANOTHER day of my life thrown in the trash, just to change the color of text. Thaaaaanks Aaaaaandroid.
For some reason, even though I set editTextStyle, if I use it in code, it does not get applied
It happens because the default styles of the TextInputLayout override the editTextStyle using the materialThemeOverlay attribute.
For example the Widget.MaterialComponents.TextInputLayout.FilledBox has this default style:
<style name="Widget.MaterialComponents.TextInputLayout.FilledBox" parent="Base.Widget.MaterialComponents.TextInputLayout">
<item name="materialThemeOverlay">
#style/ThemeOverlay.MaterialComponents.TextInputEditText.FilledBox
</item>
....
</style>
<style name="ThemeOverlay.MaterialComponents.TextInputEditText.FilledBox">
<item name="editTextStyle">#style/Widget.MaterialComponents.TextInputEditText.FilledBox</item>
</style>
I have a view I have created in XML. The view is then shown on one of two fragments. Either as the pause menu, replacing the board in my game activity, or a score summary at the end of a round on a DialogFragment.
Each TextView on my summary sets its textAppearance using an attribute declared in the theme for the view. This works without problem on my Sony Xperia Z3 Compact, running API 22. However, the text appearance doesn't seem to be applied at all on my wifes phone. Her's is a Z3 Compact running API 19. I also have a tablet running API 17 with the same problem.
On each of the devices with the problem, all the text is displayed with a very small text size. It also ignores the textColor set by the style.
The XML for each component looks like a variation on this:
<TableRow android:id="#+id/view_score_summary_group_overall_time">
<TextView
android:text="#string/time"
android:textAppearance="?scoreSummaryTextAppearanceHeading"
/>
<TextView android:id="#+id/view_score_summary_game_time"
android:layout_column="2"
android:textAppearance="?scoreSummaryTextAppearanceData"
/>
</TableRow>
The attribute is then defined in my theme like this:
<style name="ScoreSummary.Light">
<item name="scoreSummaryTextAppearanceHeading">#style/ScoreSummary.Light.TextAppearance.Heading</item>
<item name="scoreSummaryTextAppearanceTitle">#style/ScoreSummary.Light.TextAppearance.Title</item>
<item name="scoreSummaryTextAppearanceData">#style/ScoreSummary.Light.TextAppearance.Data</item>
</style>
The styles are then defined like this:
<style name="ScoreSummary">
</style>
<style name="ScoreSummary.Light">
</style>
<style name="ScoreSummary.Light.TextAppearance">
<item name="android:textColor">#color/text_score_summary_light</item>
</style>
<style name="ScoreSummary.Light.TextAppearance.Title">
<item name="android:textSize">24sp</item>
</style>
<style name="ScoreSummary.Light.TextAppearance.Heading">
<item name="android:textSize">16sp</item>
<item name="android:gravity">start</item>
</style>
<style name="ScoreSummary.Light.TextAppearance.Data">
<item name="android:textSize">16sp</item>
<item name="android:gravity">end</item>
</style>
I then set the theme on the view (on my game activity) like this:
<com.abc.def.ScoreSummaryView android:id="#+id/fragment_game_score_summary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:layout_gravity="center"
android:theme="#style/ScoreSummary.Light"
/>
So far I have tried a number of things:
Setting the attributes individually on the TextView.
android:textSize="150sp"
This worked. But if you have to set that on every component, why bother with styles at all.
Setting textAppearanceSmall instead of textAppearance. Based on this. This just made all the text slightly larger, but still didn't apply my style.
Setting style instead of textAppearance. This had the same result as setting textAppearanceSmall.
Making my style declarations extend "android:attr/textAppearance". Didn't change anything, and I'm not sure why it would but I was desperate.
I've been looking at this for ages now, and I've tried googling a whole load of things but just can't get anywhere.
This is it looking wrong. On my tablet - though it looks similar on my wifes phone.
This is how it's supposed to look. On my phone.
I am using the AppCompat theme and I want set the minHeight attribute on my buttons:
<style name="Theme.MyTheme" parent="Theme.AppCompat">
<item name="android:buttonStyle">#style/MyButtonStyle</item>
</style>
<style name="MyButtonStyle" parent="...?">
<item name="android:minHeight">60dp</item>
</style>
However, there is no Widget.AppCompat.Button style to set as the parent for MyButtonStyle. If I use android:Widget.Button, then all my buttons look like the old crappy style. I tried various other AppCompat themes like TextAppearance.AppCompat.Button, but they do not work.
Leaving out a parent theme for the button style also causes the button not to be styled correctly.
How can I customize the default Theme.AppCompat buttonStyle?
You can have Base.MyButtonStyle extend android:Widget.Holo.Button on API 14+ (in res/values-v14/styles.xml) and android:Widget.Material.Button on API 21+ (in res/values-v21/styles.xml. This style will change according to the device system version. Put your platform specific modifications here.
Then have MyButtonStyle extend Base.MyButtonStyle and define the android:minHeight here (in res/values/styles.xml). This will apply to all platforms.
You buttons then can use style MyButtonStyle.
This example assumes your minimum SDK is 14.
And yes, there's no appcompat-v7 button style (well, at least not yet).
EDIT
This assumes you're OK with Holo button on platforms older than Lollipop. It feels unobtrusive and if you can do without ripples, it should be just fine. If you want ripples I suggest you google for a third party lollipop button library.
To answer my own question, it appears AppCompat does not in fact support the Button widget presently:
AppCompat provides similar behaviour on earlier versions of Android
for a subset of UI widgets:
Everything provided by AppCompat’s toolbar (action modes, etc)
EditText
Spinner
CheckBox
RadioButton
Switch (use the new android.support.v7.widget.SwitchCompat)
CheckedTextView
The only workaround I see would be to recreate the Material button style from the Android source code, a task which extends outside the scope of my desire.
Custom Button Style With AppCompat +22
in your styles.xml
<style name="Button.Tinted" parent="Widget.AppCompat.Button">
<item name="colorButtonNormal">YOUR_TINT_COLOR</item>
<item name="colorControlHighlight">#color/colorAccent</item>
<item name="android:textColor">#android:color/white</item> </style>
in your layout.xml
<Button
android:id="#+id/but_next"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/but_continue"
android:theme="#style/Button.Tinted" />
With new MaterialComponent it is convenient to use com.google.android.material.button.MaterialButton instead of regular Button.
But to style it, there is used the different attribute in the theme
- materialButtonStyle, with this parent theme Theme.MaterialComponents.DayNight.NoActionBar.
Then the theme should look like this:
<style name="NewAppTheme"
parent="Theme.MaterialComponents.DayNight.NoActionBar">
.......
<-- IMPORTANT if you are using com.google.android.material.button.MaterialButton to style them use this parameter
<item name="materialButtonStyle">#style/ButtonStyle</item>
</style>
And in ButtonStyle you can change button attributes like this:
<style name="ButtonStyle" parent="Widget.MaterialComponents.Button.UnelevatedButton">
<item name="android:minHeight">60dp</item>
</style>
Remove the android:
<style name="Theme.MyTheme" parent="Theme.AppCompat">
<item name="buttonStyle">#style/MyButtonStyle</item>
</style>
https://stackoverflow.com/a/32363833
I am using the AppCompat theme and I want set the minHeight attribute on my buttons:
<style name="Theme.MyTheme" parent="Theme.AppCompat">
<item name="android:buttonStyle">#style/MyButtonStyle</item>
</style>
<style name="MyButtonStyle" parent="...?">
<item name="android:minHeight">60dp</item>
</style>
However, there is no Widget.AppCompat.Button style to set as the parent for MyButtonStyle. If I use android:Widget.Button, then all my buttons look like the old crappy style. I tried various other AppCompat themes like TextAppearance.AppCompat.Button, but they do not work.
Leaving out a parent theme for the button style also causes the button not to be styled correctly.
How can I customize the default Theme.AppCompat buttonStyle?
You can have Base.MyButtonStyle extend android:Widget.Holo.Button on API 14+ (in res/values-v14/styles.xml) and android:Widget.Material.Button on API 21+ (in res/values-v21/styles.xml. This style will change according to the device system version. Put your platform specific modifications here.
Then have MyButtonStyle extend Base.MyButtonStyle and define the android:minHeight here (in res/values/styles.xml). This will apply to all platforms.
You buttons then can use style MyButtonStyle.
This example assumes your minimum SDK is 14.
And yes, there's no appcompat-v7 button style (well, at least not yet).
EDIT
This assumes you're OK with Holo button on platforms older than Lollipop. It feels unobtrusive and if you can do without ripples, it should be just fine. If you want ripples I suggest you google for a third party lollipop button library.
To answer my own question, it appears AppCompat does not in fact support the Button widget presently:
AppCompat provides similar behaviour on earlier versions of Android
for a subset of UI widgets:
Everything provided by AppCompat’s toolbar (action modes, etc)
EditText
Spinner
CheckBox
RadioButton
Switch (use the new android.support.v7.widget.SwitchCompat)
CheckedTextView
The only workaround I see would be to recreate the Material button style from the Android source code, a task which extends outside the scope of my desire.
Custom Button Style With AppCompat +22
in your styles.xml
<style name="Button.Tinted" parent="Widget.AppCompat.Button">
<item name="colorButtonNormal">YOUR_TINT_COLOR</item>
<item name="colorControlHighlight">#color/colorAccent</item>
<item name="android:textColor">#android:color/white</item> </style>
in your layout.xml
<Button
android:id="#+id/but_next"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/but_continue"
android:theme="#style/Button.Tinted" />
With new MaterialComponent it is convenient to use com.google.android.material.button.MaterialButton instead of regular Button.
But to style it, there is used the different attribute in the theme
- materialButtonStyle, with this parent theme Theme.MaterialComponents.DayNight.NoActionBar.
Then the theme should look like this:
<style name="NewAppTheme"
parent="Theme.MaterialComponents.DayNight.NoActionBar">
.......
<-- IMPORTANT if you are using com.google.android.material.button.MaterialButton to style them use this parameter
<item name="materialButtonStyle">#style/ButtonStyle</item>
</style>
And in ButtonStyle you can change button attributes like this:
<style name="ButtonStyle" parent="Widget.MaterialComponents.Button.UnelevatedButton">
<item name="android:minHeight">60dp</item>
</style>
Remove the android:
<style name="Theme.MyTheme" parent="Theme.AppCompat">
<item name="buttonStyle">#style/MyButtonStyle</item>
</style>
https://stackoverflow.com/a/32363833
I'm making my app ready for Android 5.0, I'm using the latest compatibility library, here is what my style looks like.
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">#color/theme_accent</item>
<item name="colorAccent">#color/theme_accent_secondary</item>
</style>
<style name="AppThemeDark" parent="Theme.AppCompat">
<item name="colorPrimary">#color/theme_accent</item>
<item name="colorAccent">#color/theme_accent_secondary</item>
</style>
</resources>
(The ActionBar color is being set programmatically.)
Now, I want the overflow/popup menu to have the dark background like it had in the holo implementation, but I can't get it to work, here is what it looks like:
I have tried setting the popupMenuStyle but it didn't work.
How can I make the popup menu darker?
Stop using the ActionBar. If you want a ToolBar to be set up like an ActionBar, follow this guide on the android-developers blog.
It actually mentions your use case at Dark Action Bar and provides this code:
<android.support.v7.widget.Toolbar
android:layout_height=”wrap_content”
android:layout_width=”match_parent”
android:minHeight=”#dimen/triple_height_toolbar”
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
Not a full answer but what I found so far:
In past versions you needed to specify a drawable (Check https://github.com/StylingAndroid/StylingActionBar code and tutorials)
Apparently, now that is a color. To modify it you need to do specify the following theme:
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
<item name="android:actionBarPopupTheme">#style/popupNew</item>
</style>
<style name="popupNew" parent="android:ThemeOverlay.Material.Light">
<item name="android:colorBackground">#color/red</item>
</style>
</resources>
This works correctly if the theme applied to the app is just this.
If I add android:actionBarPopupTheme to my existing theme, it doesn't work. I am trying to figure out why.
Solved my problem by using this style:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">#color/theme_accent</item>
<item name="colorAccent">#color/theme_accent_secondary</item>
<item name="actionBarStyle">#style/AbStyle</item>
<item name="actionModeBackground">#color/actionmode_bg</item>
</style>
<style name="AbStyle" parent="Widget.AppCompat.Toolbar">
<item name="elevation">2dp</item>
<item name="displayOptions">homeAsUp|showTitle</item>
<!--showHome-->
</style>
<style name="AppThemeDark" parent="Theme.AppCompat">
<item name="colorAccent">#color/theme_accent_secondary</item>
<item name="actionBarStyle">#style/AbStyle</item>
</style>
I had to use Widget.AppCompat.Toolbar as the parent actionBarStyle
Add the property popupTheme to your toolbar:
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/color_primary"
app:theme="#style/Theme.AppCompat.Light"
app:popupTheme="#style/Theme.AppCompat" />
Or define a new style for your toolbar:
<style name="MyToolBarStyle" parent="Widget.AppCompat.Toolbar">
<item name="android:background">#color/green</item>
<item name="popupTheme">#style/Theme.AppCompat.Light</item>
<item name="theme">#style/Theme.AppCompat</item>
</style>
This question has already been answered for styling via XML, but I'm adding an explanation here of how to work out the solution to this and similar styling questions yourself.
First, this is the solution when using AppCompat. To your App's style.xml add actionBarPopupTheme to your theme:
<style name="Theme.MyTheme" parent="#style/Base.Theme.AppCompat.Light.DarkActionBar">
...other stuff here
<item name="actionBarPopupTheme">#style/Theme.MyTheme.ActionBarPopupTheme</item>
</style>
<style name="Theme.MyTheme.ActionBarPopupTheme" parent="#style/ThemeOverlay.AppCompat.Light">
<item name="android:textColor">#android:color/white</item>
<item name="android:background">#android:color/black</item>
</style>
Here's the steps I took to arrive at this solution (it takes a bit of detective work as the Android documentation is poor):
Open your App's style.xml in Android Studio
On the line where you App's theme is defined, put your screen cursor in the parent theme (e.g. click in #style/Base.Theme.AppCompat.Light.DarkActionBar) then press F4. This should take you to the source code for the style in the appcompat library.
Within this style I saw this line:
< item name="actionBarPopupTheme">#style/ThemeOverlay.AppCompat.Light< /item>
This looked like a possible place to change the theme of the popup. I searched for "actionBarPopupTheme" in the poor
Android developers documentation and found "Reference to a theme that should be used to
inflate popups shown by widgets in the action bar". So this was worth playing with.
I copied the appcompat line containing "actionBarPopupTheme" to my style.xml then in this line replaced the item's theme reference (the bit in bold above) with Theme.MyTheme.ActionBarPopupTheme.
In my style.xml I created my new style named Theme.MyTheme.ActionBarPopupTheme. I used the same parent that was used in the style I copied from the appcompat source (the bit in bold above).
To ensure my new popup style was working, I changed the parent style to ThemeOverlay.AppCompat.Dark then ran and tested the code on a device. The popup style changed, so now I knew my overriding of actionBarPopupTheme was the correct thing to do. Then I changed back to ThemeOverlay.AppCompat.Light.
The next challenge is to work out what item names to override in Theme.MyTheme.ActionBarPopupTheme. I changed the text and background colours. To find the correct item names that change the style of something can be tricky in some cases. One way to find less obvious style item names is to look through the style definitions in the appcompat xml file (the one you opened when pressing F4 in the 2nd step above), continually descending into parent styles (F4 again!) until you find something that may do what you want. Google searches will help here too.