EditText unreadable when disabled on some devices - android

I have a simple EditText field that shows a user's phone number on a login page. After initial login the phone number field is disabled.
This looks great on almost all of my devices (this screenshot is from a Samsung Galaxy S):
However, on my LG Nitro the text in the disabled EditText field is unreadable (I can just about see the white text if I zoom in on a high res screenshot):
I removed all my custom style rules from the EditText and the same problem occurs, so I think this is just a bad choice of system default colors for the phone.
Question 1: Can anybody confirm if my diagnosis is correct?
The only way I could make the text readable was to set the text to dark grey in code:
if (fieldDisabled)
{
// Some devices use their own default style for a disabled text field,
// which makes it impossible to read its text, e.g. the LG Nitro.
//
// The workaround is to override the text color here.
mPhoneNumber.setTextColor(Color.DKGRAY);
}
Afterwards the text was easy to read on all devices (including the LG Nitro):
I to set my custom style to use #color/black instead of the existing color, but the text was still shown as white.
Question 2: Is there a better workaround I can use?
My LG Nitro is model LG-P930 running OS 2.3.5.
My XML
Below are snippets of the XML I am using.
res/layout/myscreen.xml:
<EditText
...
android:textAppearance="#style/MyStyle">
</EditText>
res/values/styles.xml:
<style name="MyStyle">
<item name="android:textSize">14dp</item>
<item name="android:textColor">#color/blue</item>
</style>
res/values/colors.xml:
<color name="white">#ffffffff</color>
<color name="blue">#ff0000ff</color>
<color name="black">#ff000000</color>

I figured out how to change the color of the EditText text.
Using android:textAppearance does not appear to allow you to change the color of the text in an EditText (it does let you change the text size).
One alternative is to use the style attribute instead of android:textAppearance, as that will apply the text color changes, e.g.
style="#style/MyStyle"
However, I think the best solution is to use a ColorStateList. Below is my solution.
res/layout/myscreen.xml (still need textAppearance to control the text size):
<EditText
...
android:textColor="#color/edittext"
android:textAppearance="#style/MyStyle">
</EditText>
res/color/edittext.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="true" android:color="#color/black" />
<item android:state_enabled="false" android:color="#color/grey" />
</selector>
res/values/styles.xml (i.e. make MyStyle only define text size, not color):
<style name="MyStyle">
<item name="android:textSize">14dp</item>
</style>

Related

How to professionally organise the styling of buttons? (SDK 26+, min SDK 21)

What is best practice to organise styling of buttons of a professional android application? Assume a larger contemporary application (SDK 26+, min SDK 21).
This question is answerable, as both the sources of Material Design and the setup of Android Studio give enough clues and examples of the patterns of the intended professional usage. Surely the user is not limited to this patterns, but following them, makes the application play well together with the sources of Material Design and provides best maintainability.
I find several ingredients related to the styling of buttons.
#style/Widget.AppCompat.Button
#style/Widget.AppCompat.Button.Colored
#style/TextAppearance.AppCompat.Button
#style/TextAppearance.AppCompat.Widget.Button
#color/foreground_material_dark
?colorAccent
?textColorPrimary
?android:colorForeground
?textAppearanceButton
There may be more.
How are all the ingredients related?
How are they intended to be used together in professional theming?
You can look up the sources. However, even knowing all details does not give the full picture of the intended usage. This question is asking to draw the picture.
(Min SDK 21)
General Approach
Granularity
I think it an enough fine-grained approach to separate the text appearance from the backgrounds. This gives the option to combine different backgrounds with different text appearances. It also matches the two style settings provided by Button and the organisation of Material Design. Hence it addresses the question, how it is intended to be used.
The price is, that each Button needs both settings:
Button text: android:textAppearance
Button background: style
To even lower this price styles_material.xml in fact takes an advanced approach. Each button style already includes a default text appearance. So in the normal case I only have to apply the button style.
<Button
style="?defaultButtonStyle"
I follow this pattern for my own button styling, as the question is for the intended usage. If I want to modify the default, I add an alternative text appearance by setting it to android:textAppearance.
<Button
style="?defaultButtonStyle"
android:textAppearance="?smallButtonTextAppearance"
For very special buttons I still can adjust the styling on the level of the layout file. This is the lowest level of granularity.
Hint: Be aware that android:textAppearance has a very low
precedence. If you set a text attribute somewhere in the theme (or style),
you will overwrite the same attribute in all of android:textAppearance.
It works with a similar force like the "!important" annotation in CSS,
which can be a pretty pitfall.
Flexible theming
Without
If I don't plan to use different themes, I can set the styles directly into the layouts.
<Button
style="#style/My.DefaultButtonStyle"
android:textAppearance="#style/My.SmallButtonTextAppearance"
...
With
If a want to be able to exchange themes, I map all types of styles to attributes first. Then I set the styles indirectly by using the attributes. This gives me the option to connect other styles for other themes, without the need to duplicate layouts.
<Button
style="?defaultButtonStyle"
android:textAppearance="?smallButtonTextAppearance"
...
I personally prefer not to use or mix given attributes, but to fully define my own set of attributes addressing my design. So the levels of the onion stay cleanly separated.
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<!-- button text appearance -->
<attr name="defaultButtonTextAppearance" format="reference" />
<attr name="smallButtonTextAppearance" format="reference" />
<!-- button backgrounds -->
<attr name="defaultButtonStyle" format="reference" />
<attr name="alarmButtonStyle" format="reference" />
In the themes the attributes are mapped to theme specific styles.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="OtherTheme" parent="Theme.AppCompat">
<!-- button text appearance -->
<item name="defaultButtonTextAppearance">#style/OtherTheme.DefaultButtonTextAppearance</item>
...
<!-- button backgrounds -->
<item name="defaultButtonStyle">#style/OtherTheme.DefaultButtonStyle</item>
...
Button Text
If I track down the styles to the sources I come to a file data/res/values/styles_material.xml, which defines the root of all button text appearances. TextAppearance.Material.Button inherits from TextAppearance.Material, but the four relevant attributes for buttons are overwritten.
<style name="TextAppearance.Material">
<item name="textColor">?attr/textColorPrimary</item>
<item name="textColorHint">?attr/textColorHint</item>
<item name="textColorHighlight">?attr/textColorHighlight</item>
<item name="textColorLink">?attr/textColorLink</item>
<item name="textSize">#dimen/text_size_body_1_material</item>
<item name="fontFamily">#string/font_family_body_1_material</item>
<item name="lineSpacingMultiplier">#dimen/text_line_spacing_multiplier_material</item>
</style>
<style name="TextAppearance.Material.Button">
<item name="textSize">#dimen/text_size_button_material</item>
<item name="fontFamily">#string/font_family_button_material</item>
<item name="textAllCaps">true</item>
<item name="textColor">?attr/textColorPrimary</item>
</style>
It can be overwritten by my own inherited styles. It also shows, that it would be easy to write my own text appearance style without using inheritance at all.
Color
Understanding Androids text color management system is them most confusing part, because the system is quite powerful. Here comes some enlightenment.
In the above TextAppearance.Material.Button I find text color is specified by the attribute ?textColorPrimary. This attribute again is based on the attribute ?android:colorForeground.
The attribute ?android:colorForeground is the central switch to set the text colors. Be default all text colors are calculated based on this setting, also those of the buttons. For example different grades of greyed-out or opaque variants are calculated for disabled buttons, for body text, etc.
Instead of touching dozens of different places it is a good idea to set the common default text color here and rely on the default Android color calculating system as far as useful. Tweak it in details.
<item name="android:colorForeground">#color/orange_700</item>
This setting defaults to #color/foreground_material_dark.
Hint 1: If you edit the setting by use of
the Android Studio Theme Editor, it will possibly change the
value of#color/foreground_material_dark. To me it does not
feel like a good idea to change a value of material dark because
it is not my realm. Better use a reference like shown before.
Hint 2: The Theme Editor is an appropriate tool to discover
the relations of the color attributes system. This relations reveal,
when you experimentally try to edit the different attributes with the editor.
If I want a button text color that varies from the overall text color, I set it on the level of the text appearance style.
Hint 3: Using ?android:colorForeground does not work out of the
box below API 26. For a workaround see here.
Text size
The text size is the factor of the text appearance, that I typically want to directly adjust to my own design within my customised text appearance styles.
<style name="My.SmallButtonTextAppearance" parent="My.DefaultButtonTextAppearance">
<item name="android:textSize">16sp</item>
</style>
TextAppearance.Material.Button takes the text size default from the resource #dimen/text_size_button_material. There is no system with a central text size setting comparable to the text color setting system.
All caps
The root style TextAppearance.Material.Button set's all caps to true. There is not even a resource, the value is taken from. It's just hard coded.
<item name="textAllCaps">true</item>
There is a high chance, I want to set it to false in my customised button styles.
<item name="android:textAllCaps">false</item>
Font family
As with the text colors the font family typically is a system with a common central nature. How is it managed for the buttons? The root style TextAppearance.Material.Button makes use a the string resource #string/font_family_button_material.
<item name="fontFamily">#string/font_family_button_material</item>
In the file data/res/values/donttranslate_material.xml this is set to sans-serif-medium, while in the file data/res/values-watch/donttranslate_material.xml is is set to sans-serif-condensed.
<string name="font_family_button_material">sans-serif-medium</string>
<string name="font_family_button_material">sans-serif-condensed</string>
This sans-serif settings are mapped to my chosen font family within the fonts setup. Typically sans-serif is fine for button text. For further customisation of the fonts I point to this question.
Button Style
Apart from using a color for the background, a xml resource file can be applied to specify the background with fancy corners, color gradients or other graphical effects, also supporting different backgrounds for different states of the button.
This part is strongly influenced by my design. I will typically use my own background.
On the other hand there is a rich system of predefined button backgrounds resource files in material design. I would like to give a short overview here, but that's beyond my skills and seems so large to be worth a topic of it's own.
The style for the background should not contain settings for width, height or margins, as this belongs into the surrounding layout. On the other hand the padding belongs into the background style.
Button styles of Material Design
In the file data/res/values/styles_material.xml I find nine button styles I may inherit from. If I write my very own, a should not forget to set a default text appearance.
The root element is Widget.Material.Button. It set's the default text appearance to ?textAppearanceButton. Hence, setting this attribute is an option to directly use the material design button styles without inheritance and yet have your customised default text appearance.
<!-- 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 ?colorAccent is used, to set the color of Widget.AppCompat.Button.Colored. See the Android Studio Theme Editor. See #drawable/btn_colored_material.
Note that the default text appearance of Widget.AppCompat.Button.Colored varies and is not set by a customisable attribute.
<!-- Colored bordered ink button -->
<style name="Widget.Material.Button.Colored">
<item name="background">#drawable/btn_colored_material</item>
<item name="textAppearance">#style/TextAppearance.Material.Widget.Button.Colored</item>
</style>
<!-- Small bordered ink button -->
<style name="Widget.Material.Button.Small">
<item name="minHeight">48dip</item>
<item name="minWidth">48dip</item>
</style>
<!-- Borderless ink button -->
<style name="Widget.Material.Button.Borderless">
<item name="background">#drawable/btn_borderless_material</item>
<item name="stateListAnimator">#null</item>
</style>
Note that the default text appearance of Widget.Material.Button.Borderless.Colored varies and is not set by a customisable attribute.
<!-- Colored borderless ink button -->
<style name="Widget.Material.Button.Borderless.Colored">
<item name="textAppearance">#style/TextAppearance.Material.Widget.Button.Borderless.Colored</item>
</style>
Note that Widget.Material.Button.ButtonBar.AlertDialog inherits from Widget.Material.Button.Borderless.Colored. Same limitations of the default text appearance apply.
<!-- Alert dialog button bar button -->
<style name="Widget.Material.Button.ButtonBar.AlertDialog" parent="Widget.Material.Button.Borderless.Colored">
<item name="minWidth">64dp</item>
<item name="minHeight">#dimen/alert_dialog_button_bar_height</item>
</style>
<!-- Small borderless ink button -->
<style name="Widget.Material.Button.Borderless.Small">
<item name="minHeight">48dip</item>
<item name="minWidth">48dip</item>
</style>
<style name="Widget.Material.Button.Inset">
<item name="background">#drawable/button_inset</item>
</style>
<style name="Widget.Material.Button.Toggle">
<item name="background">#drawable/btn_toggle_material</item>
<item name="textOn">#string/capital_on</item>
<item name="textOff">#string/capital_off</item>
</style>
Personally I would either use one of this predefined button styles or inherit my own from Widget.Material.Button. This keeps the hierarchy of inheritance low and the code easily readable. It saves me at most three lines of code if I inherit from another style, while the code becomes less maintainable.
There are exceptions to this rule of thumb. For example #drawable/btn_borderless_material is private. So I either have to inherit from Widget.Material.Button.Colored or create a copy of the file.
Appendix
Related questions
Attributes
Defining custom attrs
Android Use custom themes to modify style attributes
Android "?colorPrimary" vs "?attr/colorPrimary"?
Inheritance issue, when using property androidTextapperance vs. property style
Colors
Setting a color based on theme
Attribute android:colorForeground not working in API 23
android themes - defining colours in custom themes
Fonts
How to set default font family for entire Android app
How to change fontFamily of TextView in Android
What is the difference between fontFamily and typeFace in android?
it's up to you and depends on your application.. also you can set a background using an xml file
eg:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" >
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="20dp" />
<solid android:color="#8c0000" />
</shape>
</item>
<item >
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="20dp" />
<solid android:color="#c62f2c" />
</shape>
</item>
</selector>

App Theme's TextColor being ignored on Samsumg Galaxy Tab 4

I have an android app where I have set the text and background colours as follows in the theme in styles.xml:
<style name="MyAppTheme" parent="Theme.AppCompat.Light">
<item name="colorPrimary">#28abe3</item>
<item name="colorPrimaryDark">#0f92ca</item>
<item name="colorAccent">#0f92ca</item>
<item name="android:textColor">#8a000000</item>
<item name="android:textColorPrimary">#de000000</item>
<item name="android:colorBackground">#fffafafa</item>
<item name="android:textColorSecondary">#8a000000</item>
<item name="android:textColorTertiary">#8a000000</item>
</style>
This works great on every device I can find to test it on. However, I have some users running the app on a Samsung Galaxy Tab 4, who are reporting that some of the text views are showing text in a very light shade of grey, almost indistinguishable from the background, instead of the very dark grey specified through the theme. This doesn't affect every TextView in the app, but an example one is shown below:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text Here"
android:id="#+id/problematicTextView"
android:layout_weight="1"
android:minHeight="25dp"
style="#android:style/TextAppearance.DeviceDefault.Medium" />
I've tried everything I can think of short of buying a Galaxy Tab 4 to debug this by trial and error, but to no avail. The only distinguishing feature between TextView that appear with the correct dark grey text as opposed to those which appear in the very light grey color is the line:
style="#android:style/TextAppearance.DeviceDefault.Medium"
The ones which work correctly have:
style="#android:style/TextAppearance.DeviceDefault.Small"
but as I understand it, this is only meant to affect the text size rather than color.
What am I missing to style the TextView text colors correctly in a way that works on all devices (targeting API level 16+)?
If you want a consistent theme across all devices, you should avoid using any DeviceDefault styles as those are the ones customized by individual manufacturers.
I'd instead suggest using one of the AppCompat TextAppearance styles such as Theme.AppCompat.Medium.

How can I style my editText as a spinner? Support to Lollipop not working

I have one EditText field that I want to stylize as a Spinner, and Im using the support library to Android Lollipop. However, I'm not able to give the correct color to the dropdown selector (the same that is used on the default spinner) .
The example can be seen here: http://imgur.com/g0ia41h
I want a darker selector, but I'm only able to get a white selector as it can be seen in the image (the first one is my editText as a spinner, with the white selector, and the second one is the real spinner, with the darker and corrector selector)
How can I change that color?
The style of the activity is this one:
<style name="SettingsTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:textSize">#dimen/text_size_medium</item>
<item name="colorPrimary">#color/h19_black</item>
<item name="colorPrimaryDark">#color/white</item>
</style>
The style of my EditText is the following:
<com.devspark.robototextview.widget.RobotoEditText
android:id="#+id/et_birth_date"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="date"
android:focusable="false"
style="?android:attr/spinnerStyle" />
Any ideas? I've been struggling for a while with this. I have no more ideas.
Thank you!!
Aha!
The AppCompat library doesn't seem to have a black version of the arrow, so what you have to do is take the white version and change the colour manually. The file name is abc_spinner_mtrl_am_alpha.9.png and you can find it here. There's one in each drawable-* folder (10 of them).
Then just add this attribute to your EditText:
android:background="#drawable/spinner_arrow_black"
You can also do this programmatically, maintaining you spinner style and without playing with the drawable files:
EditText editText = (EditText) findViewById(R.id.edit_text);
editText.getBackground().setColorFilter(Color.BLACK, PorterDuff.Mode.MULTIPLY);

TextView style in dialog, can not see text in froyo but can see in ics

I have a dialog box that I create to display messages in android. It basically contains a text view in a scrollview like this
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/about_msg"
android:text="#string/about_msg"
android:autoLink="web"
android:padding="10dip"
style="#style/DialogTextSmall" />
</ScrollView>
As you can see I have applied a style to TextView the style looks like this
<style name="DialogTextSmall">
<item name="android:textSize">#dimen/text_size_small</item>
</style>
The application theme set is like this
<style name="AppTheme" parent="android:Theme.Light">
The Problem:
On ICS api-15 it shows fine black text on white background of TextView.
The problem is When I show dialogbox in Froyo its the text does'nt seem to show even though it seems to have taken space - My guess is the color of text is same as background (greyish black)
I know I can quick fix by hard-coding black background and white text, but Is it not possible to have the default colors of platform for the text color and background of the TextView to appear, without me having to hardcode them ?
You can inherit a parent style and then only change the values you want to change. Try changing your XML to this:
<style name="DialogTextSmall" parent="#android:style/Widget.TextView>
<item name="android:textSize">#dimen/text_size_small</item>
</style>
The list of styles you can inherit can be found in the AOSP source on Github here.
EIDT:
By default text views have black text and transparent background, so you will need to set one or the other if the background behind the text view (which, again, is transparent) is black.
Inheritance from Textview style did not really help. It is a little quirky problem and here is one way to do it
http://blog.andromo.com/2011/fixing-text-colours-on-an-alertdialog-when-using-theme-light/
In my case I did it another way
Solved it for theme I inherited it from default android theme
<style name="Theme" parent="android:Theme"></style>
<style name="Theme.AppTheme" parent="#android:style/Theme.Light"/>
and
<style name="DialogTextSmall">
<item name="android:textSize">#dimen/text_size_small</item>
<item name="android:textColor">#android:color/white</item>
</style>
This way for all platforms , froyo, gingerbread and above, the dialog boxes are black and text is white on them

Changing android search dialog text color

I styled my App using a theme as described here.
<style name="MyThemeNameHere" parent="#android:style/Theme.NoTitleBar">
<item name="android:windowBackground">#drawable/background</item>
<item name="android:textColor">#eee</item>
<style>
It works like a charm in most of the App. The background is pretty dark while the text color is bright and text looks good and is easy to read.
Now in the search dialog that android creates for me the background is white, but the text color picks up my style and gets very bright and thus extremely hard to read. I tried also setting android:background to a dark color - This fixed the problem in the search dialog, but caused all textview, etc to get a dark background rather than transparent.
I want to either set the the color or the background only on the search dialog. How do I do this?
As pointed out by Mark Philip the solution can be found in this question:
Android Styling/Theming of just Search Dialog
Basically it should be styled like so
<style name="master" paret="#android:style/Theme.NoTitleBar">
<item name="android:textColorPrimary">#EEEEEE</item>
<item name="android:textColorSecondary">#EEEEEE</item>
<item name="android:textColorTertiary">#EEEEEE</item>
</style>
The root cause was that I styled the android:textColor which should never be styled.

Categories

Resources