1

I'm porting a board game from Windows Phone to Android and struggle a lot with the Android layout system.

This is the layout of the main page on Windows Phone: Screenshot of designer

I have a Grid with row definitions like this:

<Grid.RowDefinitions>
    <RowDefinition Height="Auto"/>
    <RowDefinition Height="*"/>
</Grid.RowDefinitions>

This means the controls at the bottom get whatever height is left after the board in the top row has taken what it needs. The board size updates itself at runtime to use the smallest of it's width and height, so that it becomes a square.

I'm almost getting what I want when using a RelativeLayout as root layout, but my problem with RelativeLayout as root layout is that the controls at the bottom ends up filling the entire screen.

I've done several attempts to use a TableLayout as root layout with two TableRows as children, where the first TableRow has android:height="match_parent" or "wrap_content" and the second TableRow has android:height="wrap_content". Even though I set the board size at runtime, Android doesn't resize the TableRow like Windows Phone does, so the first TableRow takes up the entire screen.

How would an expert on the Android layout system attack a problem like this? I've got an alpha release up at Google Play that looks quite well on a 7" tablet, but on phones with high DPI screens it looks like this: enter image description here


Update: As Luksprog suggested in a comment, I now use a LinearLayout with the first element having android:layout_height="0dp" and android:layout_weight="1" and the second part having android:layout_height="wrap_content". At first it didn't seem to do what I wanted, because the part at the bottom ended up taking the entire screen as I've experienced on several attempts before.

However after doing some modifications to the "wrap_content" and "match_parent" settings of the elements inside the fragments, I now get a layout that is close to what I want, and it scales quite well on high DPI phones as long as I stick with px instead of dp values for all bitmaps (against all recommendations in the Android guidelines).

Here's is the updated layout and a screenshot showing the result:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
<!-- Board -->
    <EivindApps.Ludo.Droid.Views.BoardView
        android:id="@+id/boardView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />
<!-- Game info layout -->
    <LinearLayout
        android:id="@+id/gameInfoLayout"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    <!-- Left column -->
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1">
        <!-- Red player -->
            <fragment
                android:name="EivindApps.Ludo.Droid.Views.PlayerInfoFragment"
                android:id="@+id/redPlayerInfoFragment"
                android:layout_margin="5dp"
                android:layout_alignParentLeft="true"
                android:layout_alignParentTop="true"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content" />
        <!-- Blue player -->
            <fragment
                android:name="EivindApps.Ludo.Droid.Views.PlayerInfoFragment"
                android:id="@+id/bluePlayerInfoFragment"
                android:layout_margin="5dp"
                android:layout_alignParentBottom="true"
                android:layout_alignParentLeft="true"
                android:layout_height="wrap_content"
                android:layout_weight="0"
                android:layout_width="wrap_content" />
        </LinearLayout>
    <!-- Middle column -->
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
        <!-- Dice -->
            <fragment
                android:name="EivindApps.Ludo.Droid.Views.DiceFragment"
                android:id="@+id/diceFragment"
                android:layout_centerHorizontal="true"
                android:layout_centerVertical="true"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:layout_gravity="center_vertical" />
        </LinearLayout>
    <!-- Right column -->
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1">
        <!-- Yellow player -->
            <fragment
                android:name="EivindApps.Ludo.Droid.Views.PlayerInfoFragment"
                android:id="@+id/yellowPlayerInfoFragment"
                android:layout_margin="5dp"
                android:layout_alignParentRight="true"
                android:layout_alignParentTop="true"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:layout_toRightOf="@+id/redPlayerInfoFragment" />
        <!-- Green player -->
            <fragment
                android:name="EivindApps.Ludo.Droid.Views.PlayerInfoFragment"
                android:id="@+id/greenPlayerInfoFragment"
                android:layout_margin="5dp"
                android:layout_alignParentRight="true"
                android:layout_alignParentBottom="true"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@+id/bluePlayerInfoFragment"
                android:layout_width="wrap_content" />
        </LinearLayout>
    </LinearLayout>
<!-- End of game info layout -->
</LinearLayout>

Screenshot of the layout above

Eivind Gussiås Løkseth
  • 1,862
  • 2
  • 21
  • 35
  • The problem that you have isn't very clear. If you want a part of the layout to simply take the biggest amount of space you can use several approaches. One would be a `LinearLayout` that will contain the two parts: the upper part(height = 0dp and with android:layout_weight="1", this will make this part stretch to use any available space) and the second part which will have a height of wrap_content. – user Jun 08 '14 at 12:54
  • @Luksprog thanks for your suggestion, and sorry for being unclear. To be precise, I want the layout of the Android app to be exactly like the layout of the Windows Phone app (see the first two screenshots above), and I want the layout to work on both tablets and phones with all kinds of DPI. I've updated the question with all the axml code after applying the changes that you suggested and a screenshot showing the result. What happens, is the same thing that I've been experiencing on several other attempts. The board gets no space at all. – Eivind Gussiås Løkseth Jun 08 '14 at 15:32
  • I see that you use a custom view, `BoardView`. Are you sure this isn't the reason why you see that behavior? Did you do any custom measuring in it at all? – user Jun 08 '14 at 17:57
  • @Luksprog Thanks a lot for your help! Your first comment lead me on the right track. The problem wasn't the BoardView, but wrap_content and match_parent settings in various fragments that are children of the MainActivity layout. I've now updated the question again with the current layout and a screenshot showing the result on a high DPI phone. I'll stick with this at least for now and publish a new alpha on Google Play. – Eivind Gussiås Løkseth Jun 08 '14 at 19:01

0 Answers0