Reputation: 6091
I know that the Android system provides a way to scale up the UI on the whole system, but I want something similar but just for my app. Say that in Settings I have an option to scale the UI, and using a slider the UI for my app scales up or down only on my app. Any ideas to do this the easy way?
UPDATE:
I've tried this from onCreate:
private void setScale(float screenRatio) {
Resources resources = getResources();
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
Configuration configuration = resources.getConfiguration();
configuration.densityDpi = (int) (metrics.densityDpi * screenRatio);
metrics.scaledDensity = metrics.scaledDensity * screenRatio;
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
}
but there are three downsides:
This are the same 260dpi screen but with scaled UI.
https://i.sstatic.net/wkzZb.png
https://i.sstatic.net/WF5rY.png
https://i.sstatic.net/GMYRA.png
https://i.sstatic.net/hTREN.png
Upvotes: 1
Views: 4374
Reputation: 6091
So this is the solution that I came to and here is a working example of how to implement it: https://github.com/thelong1EU/ScaleUI
1. Create a ContextWraper object that uses the custom Configuration object
As I was guessing it all had to to with the context object. The first step is to create a ContextWraper object that contains the modifications you want. You can change the locale and all other qualifiers or device properties from here. See the full list here: https://developer.android.com/reference/android/content/res/Configuration.html#lfields
public class ScaledContextWrapper extends ContextWrapper {
public ScaledContextWrapper(Context base) {
super(base);
}
@SuppressWarnings("deprecation")
public static ScaledContextWrapper wrap(Context context) {
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
DisplayMetrics metrics = resources.getDisplayMetrics();
configuration.densityDpi = (int) (metrics.densityDpi * sScaleRatio);
configuration.fontScale = sScaleRatio;
if (SDK_INT > 17) {
context = context.createConfigurationContext(configuration);
} else {
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
}
return new ScaledContextWrapper(context);
}
}
2. Setup the new context where you want the modifications to take place
If you want to change the scale of the entire Activity you need to override the attachBaseContext() and pass the modified Context object:
@Override
protected void attachBaseContext(Context newBase) {
Context context = ScaledContextWrapper.wrap(newBase);
super.attachBaseContext(context);
}
If you want to change the scale just for one fragment or even one view you need to use a LayoutInflater object constructed using the modified Context. This is an example for scaling the fragment:
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
Context scaledContext = ScaledContextWrapper.wrap(getActivity());
LayoutInflater scaledInflater = LayoutInflater.from(scaledContext);
return scaledInflater.inflate(R.layout.fragment_layout, container, false);
}
Upvotes: 4
Reputation: 10621
Font sizes specified as sp
are density independent, so changing the densityDpi
doesn't affect its appearance. Try changing Configuration.fontScale
which is a scaling factor for fonts, relative to the base density scaling.
Upvotes: 1
Reputation: 101
Android provides you full customization in designing. If you want to scale up and have the best UI
across all devices you can use different types of folder for layout
folder.
As the documentation says you can have all resources customized for different devices. https://developer.android.com/guide/practices/screens_support.html
Upvotes: 0