21

I have problem with organizing layout in android aplication. I'm dynamically creating buttons and adding them with this code to my layout:

    LayoutInflater layoutInflater = (LayoutInflater)getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    for (int i = 0; i < NO_NUMBERS; i++){

        Button btn = new Button(this);
        btn = (Button) layoutInflater.inflate(R.layout.button, null);
        btn.setId(2000+i);
        Integer randomNumber = sort.getNumbersCopy()[i];
        btn.setText(randomNumber.toString());
        btn.setOnClickListener((OnClickListener) this);
        buttonList.addView(btn);
        list.add(btn);
    }

I'm adding it to the LinearLayout:

<LinearLayout
    android:id="@+id/buttonlist"
    android:layout_alignParentLeft="true"
    android:layout_marginTop="185dp"
    android:layout_marginLeft="5dp"
    android:layout_marginRight="5dp"
    android:orientation="horizontal"
    android:gravity="center_horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">

</LinearLayout>

and i'm importing this .xml where i'm defining button layout:

<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:textSize="26dp"
android:textStyle ="bold"
android:textColor="#ffffff"
android:background="@drawable/button"
android:layout_marginLeft="8px"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"/>

Well, layout always ends up like this:enter image description here

Instead of something like this (even spce between buttons, square buttons): enter image description here

To summarize this: I have to:

  • describe button in xml
  • dynamically generate N buttons
  • add properties of described button to dynamically created ones
  • organize layout so it can evenly distribute buttons in buttonList with spaces between tham
Ante
  • 8,567
  • 17
  • 58
  • 70

3 Answers3

56

Remember, android:layout_* attributes are LayoutParams. They are arguments to the parent and affect how the parent will perform layout on that view. You're specifying layout_margin attributes on your buttons, but they're getting ignored. Here's why:

Since LayoutParams are specific to the parent view type, you need to supply an instance of the correct parent type when you inflate layouts using a LayoutInflater or else layout_ attributes on the top-level view in the layout will be dropped. (The inflater would have no idea what type of LayoutParams to generate.)

Since buttonList is your intended parent for the button views, change your inflate line to this:

btn = (Button) layoutInflater.inflate(R.layout.button, buttonList, false);
adamp
  • 28,862
  • 9
  • 81
  • 69
  • 4
    Umm, I don't think this is the problem at all. – Matthew Mar 15 '11 at 22:22
  • Well, I tried that. Your solution generated new problem. In that case layoutInflater returns buttonList. Maybe i'm using it wrong. If that is a case, how could I describe button layout in XML and add it to some button? – Ante Mar 15 '11 at 22:27
  • 5
    ups, sorry, i have missed that "false" in method call :) thanks, solved my problem! – Ante Mar 15 '11 at 23:00
  • 2
    Glad to hear it! :) `inflate`'s return value differs based on whether or not it attaches the inflated view to the parent specified in the second parameter. The third optional boolean parameter specifies whether or not the inflated view should be added to the parent if it's not null, and it defaults to `true`. (Yes, this is annoying, and we're sorry. :) ) Reference: http://goo.gl/ak6z8 – adamp Mar 16 '11 at 00:04
  • How to do it for custom concrete view, created in-place, like: val layout = LinearLayout(context, null, 0, style) Style margins are ignored here although the view type is concrete. – Kurovsky Aug 06 '18 at 11:27
2

Setting layout_weight on the buttons themselves will cause the buttons to expand without having space between them. LinearLayout never adds space between its child views.

You should wrap each one in a FrameLayout and use layout_gravity="center" on your buttons, then set layout_weight="1" on the FrameLayout.

<FrameLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="1">
    <Button android:layout_{width,height}="wrap_content"
       android:layout_gravity="center"/>
</FrameLayout>
Matthew
  • 44,826
  • 10
  • 98
  • 87
  • Well, that "layout_weight" property was my last attempt to solve this problem. It failed, of course. :) – Ante Mar 15 '11 at 22:35
  • Did you use the FrameLayout to wrap each Button? Also make sure that the buttons actually have space to expand (perhaps take off the margin parameters on your LinearLayout) – Matthew Mar 15 '11 at 22:38
  • On my nexus one is different screen size (different from this emulator) and there is enough space but the result is the same. It seems like a good solution but I don't know how could I manage buttons after that. I have to dynamically add them to layout, inflate them with properties described in XML and than do something with them. If I inflate this, what to do next? Please describe how to use this layout after that. – Ante Mar 15 '11 at 22:49
0

This also worked by embedding the TextView into a LinearLayout (vertical)

text_view.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <TextView
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:textAppearance="?android:attr/textAppearanceLarge"
              android:text="Large Text"
              android:id="@+id/textView"
              android:layout_margin="10dp"
              android:textColor="@color/white"/>

</LinearLayout>

This was embedded into another view where the root view is also a LinerLayout. A convoluted workaround...

JoelEsli
  • 451
  • 3
  • 8