Reputation: 5354
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?
Upvotes: 3
Views: 224
Reputation: 62189
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.
Upvotes: 1
Reputation: 14755
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
Upvotes: 1
Reputation: 5746
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);
}
Upvotes: 1