Razvan Cristian Lung
Razvan Cristian Lung

Reputation: 6091

Android UI scale

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:

  1. I need to restart the app in order for the changes to have effect
  2. It only scales the view and not the font size
  3. The changes are not visible in real time

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

Answers (3)

Razvan Cristian Lung
Razvan Cristian Lung

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

dev.bmax
dev.bmax

Reputation: 10621

Font sizes specified as sp are density independent, so changing the densityDpi doesn't affect its appearance. Try changing Configuration.fontScalewhich is a scaling factor for fonts, relative to the base density scaling.

Upvotes: 1

Ali Akhgar
Ali Akhgar

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

Related Questions