Skip to content Skip to sidebar Skip to footer

Android: How To Scale A Layout With Screen Size

Consider this layout (pulled from here): I'd like to understand the principles behind making this layout scale with screen size. For the square, a custom onMeasure function works

Solution 1:

If you build your views using "dp" it would, basically, be the same size for eack screen size.
In most cases you will prefer that your view will resize itself proportional to the screen size.
Of course, in most cases you will need to build separate layouts for tablets.
But, besides I can recommend you to do the next steps:

1. Add this library to your project.

2. Now in your layout you can write views like that:

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="I'm scalable!" 
    android:textSize="@dimen/_12sdp"/>

In this example your TextView will scale on each screen size.

3. Preview all screen sizes to see the result.


Solution 2:

It depends a lot on the number of custom View and ViewGroup classes you want to create. An implementation with the least number of custom classes that I could think of would be something like this (very similar to what you've described):

  • Customized FrameLayout for the largest square, with a custom onMeasure() implementation to match the height to the available width (you mentioned this one already).
  • Nested LinearLayout instances using weight to get all the grid buttons to be the same size.

The big drawback to this approach is efficiency. You would need roughly 36 LinearLayout instances to create the small 9x9 grids inside of a larger 9x9 grid...that's 36 views of pure layout overhead.


As far as text sizing, there are a couple ways I could think of to handle this. One would be to use Paint.measureTextBounds() (you can get the Paint object of any TextView to do the measurements) to determine what size you need to make the text in each button after they have been measured. Unfortunately this would be a somewhat iterative process because the Paint measures a given text based on its current settings, so you would need to:

  1. Set the text size
  2. Measure bounds
  3. Check height
  4. Repeat until the size just fits

The good news is you would only need to do this once and just apply it to all the grid buttons, but you would need to wait until the grid buttons are measured.

Another option here would be to display an image instead of text inside of something like ImageView, which can scale the content for you to its size. You could use something like the TextDrawable that I wrote to set text content as an image that is scalable without quality loss.


Now back to the layout. You could gain back a ton of efficiency by creating a custom ViewGroup to measure and lay out the grid (the name GridLayout is already taken...and it doesn't quite serve this purpose, so let's call it BlockLayout). Creating a custom BlockLayout will allow you to measure the size of each block and lay out 9 subviews in a grid with a single parent instead of 4 LinearLayout instances. This is basically the same way that you measure the overall square, just divided evenly.

You could then build the entire layout with only 10 instances of layout overhead...and even less if you can code the entire thing into a single ViewGroup.

Basically the more code you can write to flatten the view hierarchy, the better your application will run overall.

HTH


Solution 3:

To complement Devnuwired's answer, you can write a method similar to this to add his TextDrawable text to an ImageButton:

private void addText(String text, ImageButton button, int colour) {
    TextDrawable d = new TextDrawable(this);
    d.setText(text);
    d.setTextColor(colour);
    d.setTextAlign(Layout.Alignment.ALIGN_CENTER);
    button.setImageDrawable(d);
}

or alternately

private void addText(String text, int buttonID, int colour) {
    TextDrawable d = new TextDrawable(this);
    d.setText(text);
    d.setTextColor(colour);
    d.setTextAlign(Layout.Alignment.ALIGN_CENTER);
    ((ImageButton) findViewById(buttonID)).setImageDrawable(d);
}

Post a Comment for "Android: How To Scale A Layout With Screen Size"