eightx2 eightx2 - 2 months ago 12
Android Question

Making two LinearLayouts have 50% of the screen each without using layout_weight

I'm currently doing a special xml layout of a landscape screen, where 4 images are present and 2 LinearLayouts are next to each other with 2 images each. These LinearLayouts I call

linearLayout1
and
linearLayout2
.

linearLayout1
is marked with blue rectangle:

linearLayout1

linearLayout2
is marked with blue rectangle:

linearLayout2

As you can see, the first one uses ~80% of the screen, while the second one uses what's left. I don't want this of course, I want 50% for each. I can't use
layout_weight
because it's already used in the LinearLayouts themselves (positioning of the two images) and nested weights are bad for performance.

I've tried many different variations, but I simply can't get the two LinearLayouts to have 50% of the screen each. Here's the code:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/db1_root"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >

<LinearLayout
android:id="@+id/title_container"
style="@style/TitleBar" >

<ImageView
style="@style/TitleBarLogo"
android:contentDescription="@string/imgViewDesc"
android:src="@drawable/title_logo" />

<ImageView
style="@style/TitleBarSeparator"
android:contentDescription="@string/imgViewDesc" />

<TextView style="@style/TitleBarText" />

<ImageButton
style="@style/TitleBarAction"
android:contentDescription="@string/imgViewDesc"
android:onClick="onClickAbout"
android:src="@drawable/title_about" />
</LinearLayout>

<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/title_container"
android:layout_above="@+id/mobFoxView" >

<!-- LEFT COLUMN -->

<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="@+id/mobFoxView"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="@+id/linearLayout2"
android:background="@color/white"
android:gravity="center"
android:orientation="vertical"
android:weightSum="2" >

<ImageView
android:id="@+id/imgNews"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:contentDescription="@string/imgViewDesc"
android:onClick="onClickFeature"
android:src="@drawable/front_news_1" />

<ImageView
android:id="@+id/imgReleases"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:contentDescription="@string/imgViewDesc"
android:onClick="onClickFeature"
android:src="@drawable/front_releases_1" />
</LinearLayout>

<!-- RIGHT COLUMN -->

<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_above="@+id/mobFoxView"
android:layout_alignParentRight="true"
android:layout_alignTop="@id/linearLayout1"
android:background="@color/white"
android:gravity="center"
android:orientation="vertical"
android:weightSum="2" >

<ImageView
android:id="@+id/imgArtists"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:contentDescription="@string/imgViewDesc"
android:onClick="onClickFeature"
android:src="@drawable/front_artists_1" />

<ImageView
android:id="@+id/imgLabels"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:contentDescription="@string/imgViewDesc"
android:onClick="onClickFeature"
android:src="@drawable/front_labels_1" />
</LinearLayout>
</RelativeLayout>

<com.mobfox.sdk.MobFoxView
android:id="@+id/mobFoxView"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
mode="test"
publisherId="@string/mobFoxID" />

</RelativeLayout>

Answer

Well, there are two options I see available here.

  1. Screw that LINT warning and use the nested weights anyway. Phones are fast and it will make milliseconds worth of a difference since you only inflate layouts once (most of the time). Having nested layouts is only bad for performance because the inflator needs to make more passes to measure the layouts.

  2. Swap your top LinearLayout with a RelativeLayout and align the two children to an invisible View in the center like so:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/top"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
      android:id="@+id/center_point"
      android:layout_width="0dp"
      android:layout_height="0dp"
      android:layout_centerInParent="true"/>

    <LinearLayout
      android:id="@+id/left_layout"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:layout_alignParentLeft="true"
      android:layout_alignRight="@+id/center_point">
    </LinearLayout>


    <LinearLayout
      android:id="@+id/right_layout"
      android:orientation="horizontal" //default
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:layout_alignParentRight="true"
      android:layout_alignLeft="@+id/center_point">
    </LinearLayout>

</RelativeLayout>