Jack
Jack

Reputation: 241

Nested LinearLayouts Not Working

I have been trying for 2 days now to create a nested linear layout ( linear layout inside a linear layout) with little success. My master layout has 3 sections that have been weighted 45, 45 & 10. When I run that, it appears to be working great. I get 3 rectangles on the screen of different colors.

Once I create the "sub" linear layout and add it to the master, the sub layout dominates the screen. The sub linear layout is weighted 35,35 & 30. So I would expect on the screen to see the top rectangle split into 3 thinner rectangles. Instead I get the 3 rectangles that belong to the sub layout.

Any ideas?

public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

    // Ensure there is a full screen blank window to work with
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                         WindowManager.LayoutParams.FLAG_FULLSCREEN);

      testViewA = new TestView(this);
      testViewB = new TestView(this);
      testViewC = new TestView(this);

      testViewD = new TestView(this);
      testViewE = new TestView(this);
      testViewF = new TestView(this);

      testViewA.color = 0;
      testViewB.color = 1;
      testViewC.color = 2;
      testViewD.color = 3;
      testViewE.color = 4;
      testViewF.color = 5;

    LinearLayout.LayoutParams paramsA = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, 0, .45f);
    LinearLayout.LayoutParams paramsB = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, 0, .45f);
    LinearLayout.LayoutParams paramsC = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, 0, .10f);

    LinearLayout.LayoutParams paramsX = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, 0, .35f);
    LinearLayout.LayoutParams paramsY = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, 0, .35f);
    LinearLayout.LayoutParams paramsZ = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, 0, .30f);

    paramsA.setMargins(10, 10, 10, 10);
    paramsB.setMargins(10, 10, 10, 10);

    testViewA.setLayoutParams(paramsA);
    testViewB.setLayoutParams(paramsB);
    testViewC.setLayoutParams(paramsC);
    testViewD.setLayoutParams(paramsX);
    testViewE.setLayoutParams(paramsY);
    testViewF.setLayoutParams(paramsZ);

    LinearLayout sub1 = new LinearLayout(this);
    sub1.setOrientation(LinearLayout.VERTICAL);
    sub1.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
    sub1.addView(testViewD);
    sub1.addView(testViewE);
    sub1.addView(testViewF);

    LinearLayout masterL = new LinearLayout(this);
    masterL.setOrientation(LinearLayout.VERTICAL);
    masterL.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
    masterL.addView(sub1);
    masterL.addView(testViewB);
    masterL.addView(testViewC);

    setContentView(masterL);

}

Upvotes: 1

Views: 699

Answers (4)

user
user

Reputation: 87064

Your layout would work just fine but instead of adding the LayoutParams paramsA for your new sub-layout(sub1) that you actually add to the masterL LinearLayout you set a new set of LayoutParams (with width and height set to FILL_PARENT?!!?) that make your sub1 fill the entire master layout. All you have to do is set the correct LayoutParams to sub1:

    sub1.setLayoutParams(paramsA);

Note: As other said nested weight aren't so good for performance, maybe you could improve your layout with other types of layouts.

Upvotes: 1

Akhil
Akhil

Reputation: 14038

You need to :

1)set the height of the children to 0 for whom you are setting the weight.

2)set the setweightSum of the parent layout (sum of the weights of the children).

Check this code as an example which i made from your code sample:

 requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                             WindowManager.LayoutParams.FLAG_FULLSCREEN);

          TextView TextViewA = new TextView(this);
          TextView   TextViewB = new TextView(this);
          TextView      TextViewC = new TextView(this);

          TextView      TextViewD = new TextView(this);
          TextView      TextViewE = new TextView(this);
          TextView      TextViewF = new TextView(this);

         TextViewA.setBackgroundColor( Color.RED);
          TextViewB.setBackgroundColor( Color.BLACK);
          TextViewC.setBackgroundColor( Color.BLUE);
          TextViewD.setBackgroundColor( Color.CYAN);
          TextViewE.setBackgroundColor( Color.GRAY);
          TextViewF.setBackgroundColor( Color.GREEN);



       LinearLayout.LayoutParams paramsA = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, 0, .45f);
        LinearLayout.LayoutParams paramsB = new LinearLayout.LayoutParams( LayoutParams.FILL_PARENT,0, .45f);
        LinearLayout.LayoutParams paramsC = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,0, .10f);

        LinearLayout.LayoutParams paramsX = new LinearLayout.LayoutParams( LayoutParams.FILL_PARENT, 0,.35f);
        LinearLayout.LayoutParams paramsY = new LinearLayout.LayoutParams( LayoutParams.FILL_PARENT,0, .35f);
        LinearLayout.LayoutParams paramsZ = new LinearLayout.LayoutParams( LayoutParams.FILL_PARENT,0, .30f);

        paramsA.setMargins(10, 10, 10, 10);
       paramsB.setMargins(10, 10, 10, 10);

      TextViewA.setLayoutParams(paramsA);
        TextViewB.setLayoutParams(paramsB);
        TextViewC.setLayoutParams(paramsC);
        TextViewD.setLayoutParams(paramsX);
        TextViewE.setLayoutParams(paramsY);
        TextViewF.setLayoutParams(paramsZ);

        LinearLayout sub1 = new LinearLayout(this);
        sub1.setOrientation(LinearLayout.VERTICAL);

        sub1.setLayoutParams(new LayoutParams( LayoutParams.FILL_PARENT,0,0.45f));
        sub1.setWeightSum(1f);
        sub1.addView(TextViewD);
        sub1.addView(TextViewE);
        sub1.addView(TextViewF);

        LinearLayout masterL = new LinearLayout(this);
        masterL.setOrientation(LinearLayout.VERTICAL);
        masterL.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
       masterL.setWeightSum(1f);
        masterL.addView(sub1);
        masterL.addView(TextViewB);
        masterL.addView(TextViewC);

        setContentView(masterL);

Upvotes: 0

Sam Judd
Sam Judd

Reputation: 7387

First thing is do this in xml, its very difficult to read/maintain layout code (particularly when its this simple) when its written in Java. There is rarely a good reason to write in attributes like these in Java.

Second, don't nest weights, its bad for performance: http://developer.android.com/resources/articles/layout-tricks-efficiency.html You should be able to come up with an alternative layout that doesn't require nested layouts.

Third, if you absolutely must use nested weights (again you almost certainly don't), you need to set the weight of sub1. By setting its height to fill parent, rather than 0 with a weight, you're telling it to fill the screen, so its not surprising that its doing exactly what you're telling it.

Upvotes: 0

Longerian
Longerian

Reputation: 723

layout weight attribute is only useful when the children's layout parameter setted to be wrap_content and they does has extra blank space within.

Upvotes: 0

Related Questions