Design Layout for Multiple Screens

Planning custom screen layout for multiple screens

You can support different screen sizes use ConstraintLayout:

ConstraintLayout allows you to create large and complex layouts with a flat view hierarchy (no nested view groups). It's similar to RelativeLayout in that all views are laid out according to relationships between sibling views and the parent layout, but it's more flexible than RelativeLayout and easier to use with Android Studio's Layout Editor.

You can use those attributes to specify your views size in precents:

app:layout_constraintWidth_percent=".5"
app:layout_constraintHeight_percent=".5"

For example, single button that is equal to 50% of the screen both in height and width:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">

<Button
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent=".5"
app:layout_constraintHeight_percent=".5"/>

</androidx.constraintlayout.widget.ConstraintLayout>

And it will look something like this:

enter image description here

One more thing, because different phones got different screen size you better not use fixed size dimensions (50dp for example )on your views.

I can recommend using ConstraintLayout with guidelines and Chains to support different screen sizes (In addition to what I mentioned above - app:layout_constraintWidth_percent and app:layout_constraintHeight_percent).

Design Layout For Multiple Screens

<supports-screens
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:xlargeScreens="true"
android:anyDensity="true" />

You should probably read this:

Best layout configurations for multiple screen support

Using a LinearLayout and setting a layout weight on child views of the LinearLayout can be a good way of applying flexible design. Obviously in cases where it's appropriate to use a LinearLayout.

For example you might have a LinearLayout with two LinearLayout child views. One view you'd like to take up a third of the display, and the other view two thirds. This could be fiddly to set for multiple different displays as on a smaller device it might be 300dp and 600dp but on a larger device it will likely be something very different. However, by using layout weight the proportions will automatically be calculated. Eg:

<LinearLayout
android: orientation="vertical"
android: layout_width="match_parent"
android: layout_height="match_parent">

<LinearLayout
android: orientation="vertical"
android: layout_width="match_parent"
android: layout_height="0dp"
android: layout_weight="1">

...

</LinearLayout>

<LinearLayout
android: orientation="horizontal"
android: layout_width="match_parent"
android: layout_height="0dp"
android: layout_weight="2">

...

</LinearLayout>

</LinearLayout>

layout for multiple screens

Your question is a complex one, but the short answer is that Android has different screen types and sizes, and therefore the determining factor on which resource gets used are:

  • Localization
  • Pixel Density of your device

Android looks at your Pixel density and determines which resource to use (if you specified any resources for large or small devices). But for this to work, you need to follow the localization and resource qualifier precedence. An example below:

Which Resource Takes Precedence?

I recommend you take a look at Localization , Alternative Resource and Different Screen Densities. If your folder qualifiers are not setup correctly, Android will ignore these resources and use the default one. Your resource folder should look something like this:

res/
drawable <- default
drawable-ldpi <- Alternative resources for low to large pixel densities
drawable-mdpi
drawable-hdpi
drawable-xhdpi
drawable-xxhdpi
drawable-xxxhdpi
values-sw600dp/
values-fr/ <- Values for french resources
layout/ <- Layout default
layout-land/ <- Alternative layout for landscape orientation

You can also Google these if the Android Developer Guide is too vague for you. I hope this helps

Fragment design: Adapting to multiple screen layouts by showing/hiding fragments within a single Activity?

This answer by @Taylor Clark was pretty informative. However, it wasn't an actual sharing of experience with using the single-activity approach as I asked in my original question. I set out to modify the News Reader example from the Android developer guide to use the single-activity approach and came up with a workable solution.

What remains to be seen is what are the use cases where this approach is preferable over the multiple-activity method (or whether there are any such cases at all). Also, I haven't looked in detail about the 3-pane scenario described in Edit 1 of my question.

I hope to post my entire project shortly, but here is a quick overview of how I went about it:

  • Single Activity: NewsActivity
  • Two Fragments: TitlesListFragment and DetailsFragment
  • Both fragments are always present in NewsActivity. Depending on the current dual-pane-ness, I show/hide the appropriate fragment.

Some problems I came across:

Designating a Layout as Dual-pane or not:

In the original News Reader example, dual-pane layouts have a FrameLayout for holding the news Details. We figure out whether we are currently in a dual-pane layout by testing for the existence of this Frame Layout.

However, in my solution, both fragments are always present in all layouts. I hacked this by including a View with id dualPane and android:visibility="gone" in those layouts that I want to be dual-pane and omitting this view in the single-pane layout. Then, it was a matter of

mDualPane = findViewById(R.id.dualPane)!=null;

EDIT:

There are better ways to designate dual pane-ness than having a dummy view. The one I prefer is to create a boolean resource. For example, I have a config.xml as follows:

<resources>
<bool name="dual_pane">false</bool>
</resources>

I can then place additional config.xml files in folders like values-xlarge-land, values-port or values-sw600dp etc and adjust the boolean value to true or false as I desire.

Then, in the code it is a matter of getResources().getBoolean(R.bool.dual_pane);

Closing the Details Fragment

This was a problem of differentiating between the Activity close and the Fragment close. In the end, I had to override onBackPressed() as follows:

  • In dual-pane mode, just call super.onBackPressed();
  • In single-pane mode, if we are in TitlesListFragment, call super.onBackPressed();
  • In single-pane mode, if we are in DetailsFragment, then treat it as closing the fragment. This means hiding it and showing the TitlesListFragment.

This is not ideal, but it is the best I could come up with.

EDIT:

Based on the suggestion by @SherifelKhatib in the comments, there is a much cleaner way to handle back-button presses: Simply add to the Fragment backstack, the transaction of showing/hiding the details fragment. That way, when you press the back button, the fragment transaction is reversed. You can also pop the backstack manually if you wish to do so on other button clicks.



Related Topics



Leave a reply



Submit