Android layout resources for Accessibility vision impairment - android

Android applications currently support different layout resources based on orientation, screen size, day and night etc.
However, I would like to provide layouts targeted at users with vision impairments, for instance use layouts with YELLOW background and BLACK text.
Have I missed something that Android already supports?
Can I implement custom res/layout-WAI or res/layout-DDA folders?

You can't create custom configuration qualifiers.
The current supported qualifiers are listed here.
I will suggest the following workaround (Example):
Create a special layout for WAI for each existing layout, with the same name, but with the suffix "_wai"
example_layout.xml
example_layout_wai.xml
Create a method to resolve the appropriate layout based on system needs. Say we have a method isWAI(), resolve method will look something like:
public int resolveLayoutResourceID(int layoutResID) {
int newLayoutResID = layoutResID;
if (isWAI()) {
String layoutResName = getResources().getResourceEntryName(layoutResID);
String newLayoutResName = layoutResName + "_wai";
newLayoutResID = getResources().getIdentifier(newLayoutResName, "layout", getPackageName());
}
return newLayoutResID;
}
Create a BaseActivity class for all your classes (or use a utility static function), that will override the setContentView method. There you will add a logic to select the layout.
#Override
public void setContentView(int layoutResID) {
int newLayoutResID = resolveLayoutResourceID(layoutResID)
super.setContentView(newLayoutResID);
}

Color (YELLOW background and BLACK text), fonts and font size is a topic for Styles and Themes.
Unless visually imapaired people need own layouts (arrangement, ordering of gui elements) you can implement a setting with a style chooser that can be applied to every layout

Instead of providing two different layouts, you can parametrize views in a single layout. Thus, views of your layout would take parameters (e.g. background color, text color) from the context theme they are inflated in.
So, this is what we want to achieve:
<android.support.constraint.ConstraintLayout
android:background="?attr/bgColor"
... >
<TextView
android:textColor="?attr/textColor"
... />
</android.support.constraint.ConstraintLayout>
?attr/someAttribute would be taken from the theme of the current context.
Create attributes at attrs.xml in values/:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyAttrs">
<attr name="bgColor" format="reference|color"/>
<attr name="textColor" format="color"/>
</declare-styleable>
</resources>
In styles.xml declaring two themes extending from a common theme:
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
...
</style>
<style name="AppTheme.Default">
<item name="bgColor">#color/red</item>
<item name="textColor">#color/blue</item>
</style>
<style name="AppTheme.Accessibility">
<item name="bgColor">#color/orange</item>
<item name="textColor">#color/yellow</item>
</style>
</resources>
Then, in your activity perform the assertion and set a correct theme:
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
setTheme(isAccessibility ? R.style.AppTheme_Accessibility : R.style.AppTheme_Default);
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
...
}
Or, if you have to do it on runtime, you may use ContextThemeWrapper to inflate specific view with appropriate theme.
Context wrapper = new ContextThemeWrapper(MyFragment.this.getContext(), R.style.AppTheme_Accessibility);
// inflating with a `wrapper`, not with the activity's theme
View themedView = View.inflate(wrapper, R.layout.some_layout, parent);
This is much better approach then providing two separate layouts, because it refrains you from maintaining two layouts when a change happens in UI.

Related

Run a custom Dialog layout using Theme/Style

I need to run a custom dialog layout using only theme/style options. Running custom Dialog layout by code is not an option for me. I think this should be possible by mean of attributes "android:layout", "android:dialogLayout", "*android:dialogCustomTitleDecorLayout", "*android:dialogTitleIconsDecorLayout", "*android:dialogTitleDecorLayout".<br/><br/>
My Activity onCreate load layout in a Dialog Style:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTheme(R.style.MyDialog);
setContentView(R.layout.mydialog);
this.setTitle("A title");
}
style xml:
<style name="MyDialog" parent="android:Theme.Holo.Light.Dialog">
<item name="android:windowTitleStyle">#style/MyDialog.WindowTitle</item>
<item name="android:layout">#layout/dialog_title</item>
<item name="android:dialogLayout">#layout/dialog_title</item>
<item name="*android:dialogCustomTitleDecorLayout">#layout/dialog_title</item>
<item name="*android:dialogTitleIconsDecorLayout">#layout/dialog_title</item>
<item name="*android:dialogTitleDecorLayout">#layout/dialog_title</item>
</style>
<style name="MyDialog.WindowTitle">
<item name="android:maxLines">1</item>
<item name="android:scrollHorizontally">true</item>
<item name="android:textAppearance">#style/TextAppearance_WindowTitle</item>
</style>
<style name="TextAppearance_WindowTitle">
<item name="android:textSize">32sp</item>
<item name="android:textColor">#+color/verdeTI</item>
</style>
Please, note that Text colour of the title is correctly applied (#+color/verdeTI) so I am confident the cascading styling is right but it seems none of the layout options work at all because I continue to see the standard Dialog Layout. My "dialog_title" use a completely different ImageView for divider so I can be sure when it is loaded.
The custom divider is just the main reason because I need a different layout.
Update 15/4/2014
Android theme Guide stats:
Some style properties, however, are not supported by any View element and can only be applied as a theme. These style properties apply to the entire window and not to any type of View. For example, style properties for a theme can hide the application title, hide the status bar, or change the window's background. These kind of style properties do not belong to any View object. To discover these theme-only style properties, look at the R.attr reference for attributes that begin with window. For instance, windowNoTitle and windowBackground are style properties that are effective only when the style is applied as a theme to an Activity or application. See the next section for information about applying a style as a theme.
OK attributes starting with "window" are applied only in Themes not in Styles. What's about *Layout attributes ? When they are applied ?
You can try by passing ThemeName as argument of constructor like this way.
public class TestDialog extends Dialog{
public TestDialog(Context context) {
super(context, R.style.YourTheme);
// TODO Auto-generated constructor stub
}
}
Add window feature if you require.
Make object of this class in any Activity so you can use Dialog property.
:-
More info https://stackoverflow.com/a/18224754/942224
i was using this way. so it may be help you.
You can try by creating your required layout file and opening it with an activity class just in the manifest add this code to your activity
android:theme="#android:style/Theme. Dialog"
But you will be getting title bar in your dialog with this which is your label name for your activity. To remove it add this code before setContentView
requestWindowFeature(Window. FEATURE_NO_TITLE);

Use appropriate colors irrespective of themes

I want my activity to have two possible themes, say Theme_Holo and Theme_Holo_Light, as selected by the user. I need to programmatically draw things like horizontal dividers in this activity. The color of the divider should depend on the selected theme. How can I do that easily?
Ideally there should be a name for the standard color of a divider irrespective of the theme used, and the actual RGB realization of that color name would match the selected theme automatically. Is there such thing? It seems unlikely to me that the programmer needs to hardcode RBG values.
Of course, the divider is only an example. I would also like to name the color of EditText, or other widgets, in a way that does not depend on the theme.
In your Activity's onCreate() method(s), before calling setContentView(), set the theme using this.setTheme(customTheme);
or give it a try, Using Themes in Android Applications
You can create your own theme attributes and use them in your app's themes, and allow the user to switch between your app's themes.
First, make a file called attrs.xml in /res/values folder and define some theme attributes:
<resources>
<attr name="myDividerColor" format="color" />
</resources>
Next, make two themes in your /res/values/styles.xml (or in /res/values/themes.xml if you do your themes and styles separately). One theme extends Android's dark theme and one extends Android's light theme. Add your custom attributes to your themes:
<resources>
<!-- Dark theme -->
<style name="AppTheme_Dark" parent="#android:Theme.Holo">
...
<item name="myDividerColor">#color/divider_dark</item>
</style>
<!-- Light theme. -->
<style name="AppTheme_Light" parent="#android:Theme.Holo.Light">
...
<item name="myDividerColor">#color/divider_light</item>
</style>
</resources>
Note that I used name="myDividerColor", NOT android:name="myDividerColor"
Finally, in your Activity code you can get the color as follows:
// the attrs you want
int[] attrs = {R.attr.myDividerColor};
// get attr values for the current theme
TypedArray a = obtainStyledAttributes(attrs);
// first arg is the index of the array, in same order as attrs array above
// second arg is a default value (if not defined or not a resource)
int dividerColor = a.getColor(0, Color.TRANSPARENT);

Custom background color does not cover whole background

I've written a simple custom style in xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Light">
<item name="android:textColor">#color/text_light</item>
<item name="android:background">#color/background_light</item>
</style>
</resources>
However, when I apply it, the text color is correctly set for every element of the view, whereas the background color is not set for the whole screen, but only for the single views inside it (for example listviews, textviews, buttons).
This is the code I use to set the theme:
public void onCreate(Bundle icicle) {
this.setTheme(R.android.Light);
super.onCreate(icicle);
How can I change the background color for the whole layout?
<item name="android:windowBackground">#color/background_light</item>
<item name="android:colorBackground">#color/background_light</item>
Note that the color needs to supplied as a separate resource here because the android:windowBackground attribute only supports a reference to another resource; unlike android:colorBackground, it can not be given a color literal.
(quoted from http://developer.android.com/guide/topics/ui/themes.html)
You must apply a theme to an Activity or application to apply the background image across the whole application.
Here is a link check out this tutorial

Change whole application's text color programmatically

I would like to change the whole application's text and background color in Java, is this possible? With this I mean to change the color of every item in the application (TextViews, ListView items, everything).
Is this possible?
I have tried using a custom-made style but I can't make it work. Here is the xml file (put in the res/layout/values folder):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Light">
<item name="android:textColor">#00FF00</item>
</style>
</resources>
Let's say I just want to change the text color for now.
Now I call this style in my application like this:
public void onCreate(Bundle icicle) {
Activity.setTheme(android.R.style.light);
super.onCreate(icicle);
setContentView(R.layout.main);
But I get the error light cannot be resolved or is not a field.
Update:
One way I found to do this programmatically is to restart the activity, calling
this.setTheme(R.style.Light);
onCreate(null);
However, this works only for the current activity and not for the whole application. It would be great if it were possible to do this launching another activity, not only the current one.
You're trying it in a bit to simple way. Like this you're just adjusting your general Activity's background instead of all the different Views that are out there.
In order to try and adjust every type of View (Button, TextView etc) you'll need to address all their own styles to overwrite them.
Per example if you want to adjust Button you'll need in your own general style:
<item name="android:buttonStyle">#style/ButtonHoloDark</item>
This will point at your own custom style, which takes its parent from the Android's standard Button.
<style name="ButtonHoloDark" parent="android:style/Widget.Button">
<item name="android:background">#drawable/btn_default_holo_dark</item>
<item name="android:textColor">#ffffff</item>
</style>
Be warned, doing this for every View will take you quite some themes and styles.
You can find a great example how to do this exactly in theHoloEverywhere lib, which basically does the same for creating a holo theme backported to Android 2.2 or so
Finally, drop the Activity.setTheme(android.R.style.light); stuff, and just set your own theme via the manifest.
Ok so I found one possible solution, which is to pass the theme information between the activities using intents and the putExtra method.
Code for the first activity (the caller):
Intent i = new Intent(this, ActivityToCall.class);
i.putExtra("key", R.style.Light);
startActivity(i);
Code for the second activity (the called one):
public void onCreate(Bundle icicle) {
int theme = getIntent().getIntExtra("key",-1);
this.setTheme(theme);
super.onCreate(icicle);
// other code...
I don't know if it's the best possible approach but at least it works.
The attributes you want change are:
<style name="AppTheme" parent="android:style/Theme.Holo">
<item name="android:textColorPrimary">...</item>
<item name="android:textColorSecondary">...</item>
</style>
There are a few other ways to change them: Please Refer to this information
You can then set this Theme via the Manifest or setTheme(R.style.AppTheme) in your Activity's onCreate(...)

Best practice for providing multiple Android application themes

I'm trying to work out how to organize an android application that will have multiple themes. here's a simplified example of my problem,
2 themes, "light" and "dark",
within each theme, two text colors: "enabled" and "disabled"
now the problem is that when i define my TextView, i don't want to call out "light" or "dark" there, i want to just specify the theme at the application level and have it applied. basically, i want CSS selectors. i want to be able to define my theme like,
<style name="Light.enabled" .../>
<style name="Light.disabled" .../>
and my text view like,
<TextView style="#style/.enabled" .../>
<TextView style="#style/.disabled" .../>
and have it apply "enabled" or "disabled" based on whether i've called out "light" or "dark" at the application level.
this page,
http://www.androidengineer.com/2010/06/using-themes-in-android-applications.html
shows an app that
defines a style, say "light.enabled"
#000000
defines an attribute reference, say "enabled"
defines a style (theme) item like,
#style/light.enabled
uses the attr to define the style in the view,
this is what i want, but it doesn't work for me. the only diff is that i'm using an appwidget. the author sets the theme on the activity. the only place i can set it is Context.setTheme(), and at the "application" tag in the manifest. neither of which seems to make a difference.
You can't apply themes to app widgets. You'll just need to have different XML that uses different styles.
Also, it is confusing when you talk about light vs. dark and enabled vs. disabled as similar things. They are very different in the platform.
Light and dark are actual "themes" as the platform defines it, which is a set of default values for resource attributes, rooted off of android:style/Theme. These are changed with android:theme in the manifest or setTheme() in the API.
enabled and disabled are states. They are used with StateListDrawable (via tag in drawable/) or ColorStateList (via tag in color/) to pick a drawable/color based on the enabled state.
For example here is a color that changes based on state:
https://android.googlesource.com/platform/frameworks/base/+/master/core/res/res/color/primary_text_dark.xml
And here is a drawable that changes based on state:
https://android.googlesource.com/platform/frameworks/base/+/master/core/res/res/drawable/btn_default.xml
If you are trying support multiple themes in application.
Define theme in values/styles.xml
<style name="AppTheme" parent="Theme.AppCompat.Light">
#drawable/ic_mode_comment_white_24dp
...
#drawable/ic_subject_black_24dp
define colors in colors.xml
<resources>
<color name="colorPrimary">#FF9800</color>
</resources>
switch themes in activity runtime
public abstract class BaseActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
if (PreferenceManager.getDefaultSharedPreferences(this)
.getBoolean("pref_dark_theme"), false)) {
setTheme(R.style.AppTheme_Dark);
}
super.onCreate(savedInstanceState);
}
}
follow this articles part1 and part2
I add many more themes to the android app. But work only if-else statements.
My code:
if (sharedPreferences.getString("color_option", "Blue").equals("Blue")) {
setTheme(R.style.RedTheme);
} else {
setTheme(R.style.BlueTheme);
}
Next Step
if (sharedPreferences.getString("color_option", "Blue").equals("Blue")) {
setTheme(R.style.RedTheme);
} else if(sharedPreferences.getString("color_option", "Blue").equals("Blue")) {
setTheme(R.style.BlueTheme);
} else {
setTheme(R.style.HTheme);
}
Both Code does not work only Selected two themes not selected the third theme (Not Work). I add multiple or more themes.

Categories

Resources