0

I am writing a simple android app that has a vertical parent LinearLayout. As children, I want a ScrollView, two edit texts, and then a button.

Inside the scrollView is a number of buttons. When I put many buttons in there, the ScollView takes up the entire screen. I still want the EditTexts and final button to be visible.

public class MainActivity extends AppCompatActivity
{
    LinearLayout mainLayout;
    ScrollView scrollView;
    LinearLayout fileSelector;

    EditText name;
    EditText password;
    Button submit;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

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

        fileSelector = new LinearLayout(this);
        fileSelector.setOrientation(LinearLayout.VERTICAL);
        scrollView = new ScrollView(this);
        scrollView.addView(fileSelector);

        mainLayout.addView(scrollView);

        name = new EditText(this);
        password = new EditText(this);
        submit = new Button(this);
        submit.setText("Login");


        for(int i=0; i<100; i++)
        {
            Button b = new Button(this);
            b.setText("hello");
            fileSelector.addView(b);
        }

        mainLayout.addView(name);
        mainLayout.addView(password);
        mainLayout.addView(submit);

        setContentView(mainLayout);
    }


    public void onClick(View v)
    {


    }
}

enter image description here

I would like to know the solution programatticaly.

Matthew
  • 3,886
  • 7
  • 47
  • 84

2 Answers2

1

Change this line:

mainLayout.addView(scrollView);

To this instead:

LinearLayout.LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0);
params.weight = 1;

mainLayout.addView(scrollView, params);

LinearLayout supports the concept of weight, which will "stretch" views based on how much space there is available in the parent LinearLayout.

In this case, you make the ScrollView be zero pixels tall while you leave the two EditTexts and the submit Button their normal size. This won't fill up the LinearLayout, so then weight is applied. All views with weight get the extra space divided up between them based on the ratio of their weights, but here we only have one view with weight so it just gets all the extra space.

This means that your EditTexts and submit Button will always be visible, and the ScrollView will get whatever space is left, no matter what size the screen is.

Ben P.
  • 52,661
  • 6
  • 95
  • 123
-1

The solution was to add this... scrollView.getLayoutParams().height = 200; Which I got from this post Set ImageView width and height programmatically?

Matthew
  • 3,886
  • 7
  • 47
  • 84
  • 2
    That's the wrong solution, it hardcodes the height. The correct answer is to use a RelativeLayout or ConstraintLayout as the parent, so you can add a rule that the scrollview is above the footer, or a constraint such that it ends up like that. LinearLayout is the wrong tool. – Gabe Sechan Dec 17 '18 at 20:11
  • That is good to know. I am unfamiliar with either of those views. – Matthew Dec 17 '18 at 20:21
  • Can you give me an example with programmatically setting up the solution? – Matthew Dec 17 '18 at 20:24
  • @GabeSechan I agree that hardcoding the height is a bad idea, but I disagree that LinearLayout is wholly inappropriate for this case. If I understand OP correctly, this is exactly what `weight` is for. – Ben P. Dec 17 '18 at 23:34
  • @BenP Weight is only appropriate if he wants the footer to hold a percentage of the screen. Which is rarely the case. If he wants the footer to size itself and the scroll view to take the remaining space, the correct answer is a Relative or Constraint layout. Especially given that its a footer- a linear layout with weights won't easily allow you to put it to the bottom of the screen regardless of the height of the scroll view. Either of the other solutions are far cleaner – Gabe Sechan Dec 17 '18 at 23:38
  • @GabeSechan it feels like you misunderstand how weight works. A vertical LinearLayout holding a `0dp` / `weight=1` child followed by three `wrap_content` children will always position the three "footer" children at the bottom of the screen and has nothing to do with percentages of the screen size. – Ben P. Dec 17 '18 at 23:40
  • @BenP. No, I understand perfectly how weight works. It lays out sizes by proportion of the total weight (or weightsum if given). YOu're trying to shoehorn it into a place where it won't work well, or standup to maintenance and revision. A LinerarLayout is the wrong solution here. – Gabe Sechan Dec 17 '18 at 23:41
  • @GabeSechan I just don't see how you can believe that. What about a single `0dp` view with weight won't work well or stand up to maintenance or revision? A specific example, please. – Ben P. Dec 17 '18 at 23:44
  • @BenP. When you want to add something to the view later, and then have to rejigger the whole thing. I absolutely tell you that if a junior put that in a code review for this usecase, I'd tell him to rewrite it using the right tool. There are uses for weight, but this is not one. There are better, more flexible tools written for this exact usecase, use one of them. – Gabe Sechan Dec 17 '18 at 23:45
  • @GabeSechan I guess we're at an impasse, then. Unless some higher authority can tell us what Google was thinking when they invented weight, I will continue to support the idea of using a single `0dp` child with weight as the preferred way to fill all the space next to other fixed-width views. Thanks for the chat. – Ben P. Dec 17 '18 at 23:49