3

I have a LinearLayout which includes a Fragment and a FrameLayout. I want to use layout_weight for them since, I want the Fragment to occupy only a smaller part of the screen whereas as the FrameLayout should occupy a larger part of the screen. I want the layout_weight to be applied only to the width part and not the height. I also want the layout_weight to change when orientation of the tablet changes. For Eg. when it's in portrait mode, I want the Fragment to occupy 3/10th of the screen space and FrameLayout to occupy 7/10th whereas in Landscape mode, I would want the Fragment to occupy 2/10th of the screen space and FrameLayout to occupy 8/10th of the screen space.

I have two separate layouts for landscape and portrait mode, but it's not working. I am not sure what is the mistake here :-(

layout-large-land\frame_main_activity.xml

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:baselineAligned="false"
    android:orientation="horizontal"
    android:weightSum="10"
    android:paddingTop="10dip"
    android:paddingBottom="10dip"
    android:paddingRight="10dip" >

    <!-- This fragment takes the left area fixed for menu -->

    <fragment
        android:id="@+id/left_pane_fragment"
        android:name="MenuFragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="2" />

    <!-- A place holder which is filled by relevant content later -->

    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="8"
        android:background="#FFFFFF" />
</LinearLayout>

and

layout-large-port\frame_main_activity.xml

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:baselineAligned="false"
    android:orientation="horizontal"
    android:weightSum="10"
    android:paddingTop="10dip"
    android:paddingBottom="10dip"
    android:paddingRight="10dip" >

    <!-- This fragment takes the left area fixed for menu -->

    <fragment
        android:id="@+id/left_pane_fragment"
        android:name="MenuFragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="3" />

    <!-- A place holder which is filled by relevant content later -->

    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="7"
        android:background="#FFFFFF" />
</LinearLayout>

The issue is that, it picks any one of the layout_weight for both the orientations and doesn't update the layout_weight on orientation change. For example, in the above case, it will only pick layout_weight of 2,8 for both landscape and portrait modes and won't update it based on orientation change.

I am not sure what's going wrong here. I have checked various tutorials and have tried a lot of things on various forums but couldn't find anything which solves thing issue.

animesh143
  • 91
  • 9

2 Answers2

3

So the correct solution which I found for the intended behavior is handling orientation changes programmatically.

In the onConfigurationChanged of my Activity, I have the following code :-

// Checks the orientation of the screen
View leftPaneFragment = findViewById(R.id.left_pane_fragment);
View contentFrame = findViewById(R.id.content_frame);

if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
leftPaneFragment.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
                LayoutParams.MATCH_PARENT, 8f));
contentFrame.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
                LayoutParams.MATCH_PARENT, 2f));
}
else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
leftPaneFragment.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
                LayoutParams.MATCH_PARENT, 7f));
contentFrame.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
                LayoutParams.MATCH_PARENT, 3f));
}

In addition, I have also added the following in the AndroidManifest.xml:-

android:configChanges="orientation|screenLayout|screenSize"

Lists configuration changes that the activity will handle itself. When a configuration change occurs at runtime, the activity is shut down and restarted by default, but declaring a configuration with this attribute will prevent the activity from being restarted. Instead, the activity remains running and its onConfigurationChanged() method is called.

References :- http://developer.android.com/guide/topics/manifest/activity-element.html http://developer.android.com/guide/topics/resources/runtime-changes.html

animesh143
  • 91
  • 9
0

Ensure you are not added the attribute android:configChanges="orientation|screenLayout|screenSize" in your calling activity in AndroidManifest.xml .

Rajkumar Nagarajan
  • 1,091
  • 1
  • 10
  • 6
  • I already tried doing that as I had read it on some solution on stackoverflow itself. But the issue with this solution is that it always redraws the entire UI again. I have a file structure on the right hand side and due to the redraw, I notice a blank frame on the right for few seconds which looks ugly and will surely come as a bug on us. – animesh143 May 22 '14 at 09:34
  • If you added androd:configChanges then you will need handle the layout's weight on your java code. Place your code to change the value of layout's weight within onConfigurationChanged method. – Rajkumar Nagarajan May 22 '14 at 10:27
  • Yes. The same was suggested was Rizwan and it works perfectly fine :-) I will post the exact snippet I used, later as I am not allowed to answer my own question within 8 hours of posting. – animesh143 May 22 '14 at 10:32