0

I have a custom LinearLayout. Inside that layout I want to place a couple widgets. I could create the widgets at runtime, but would rather load them from XML.

What I have below works, but I believe it is creating two LinearLayouts, one inside the other. I'd like to simply, in this example, create the Button and EditText inside the CustomLayout. Using XML, how can I do this?

Here is a bit more detail (edit: below this example, I've included a corrected version):

<com.example.test.MyActivity
  ... />
  <LinearLayout
    ... />
    <com.example.test.CustomLayout  ***** this is the custom linear layout
      android:id="@+id/custom"
      android:orientation="horizontal"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content" />
    <View
      ... other stuff ... />
</com.example.test.MyActivity>

And here's the XML for the CustomLayout contents:

<LinearLayout
  ... />
  <Button
    ... />
  <EditText
    ... />
</LinearLayout>

And finally, the code for LinearLayout:

public class CustomLayout extends LinearLayout
{
  public CustomLayout (Context context, AttributeSet attrs)
  {
    super(context, attrs);
    Activity act = (Activity)context;
    LayoutInflater inflater = act.getLayoutInflater();
    View view = inflater.inflate (R.layout.custom_layout, this, false);
    addView (view);
  }
  ...
}

Corrected Version

<com.example.test.MyActivity
  ... />
  <LinearLayout
   android:id="@+id/outer_layout
   ... />

    ... other stuff ... 
  </LinearLayout>
</com.example.test.MyActivity>

And here's the XML for the CustomLayout contents:

<merge
  ... />
  <Button
    ... />
  <EditText
    ... />
</merge>

The code to instantiate CustomLayout

public void addCustomLayout()
{
  LinearLayout outerLayout = (LinearLayout) findViewById (R.id.outer_layout);
  CustomLayout customLayout = new CustomLayout (getContext(), null);
  outerLayout.addView (customLayout, 0);
}

And finally, the code for CustomLayout:

public class CustomLayout extends LinearLayout
{
  public CustomLayout (Context context, AttributeSet attrs)
  {
    super(context, attrs);
    Activity act = (Activity)context;
    LayoutInflater inflater = act.getLayoutInflater();
    View view = inflater.inflate (R.layout.custom_layout, this, true);
  }
  ...
}
Peri Hartman
  • 19,314
  • 18
  • 55
  • 101
  • Have You tired: ? what is the result? Have You other linearlayout methods overridden? – sandrstar Sep 22 '12 at 01:26
  • Please don't start every question with *android: title...* . All you have to do is tag the question with the `android` tag, every user will know that the question is about android. – user Sep 22 '12 at 08:50
  • makes sense, and thanks for cleaning up my titles. – Peri Hartman Sep 22 '12 at 15:27

1 Answers1

1

What I have below works, but I believe it is creating two LinearLayouts, one inside the other.

Indeed you'll have an extra LinearLayout(from the xml layout which contains the Button and the EditText) in CustomLayout. To avoid this you have at your disposal the merge tag. You'll use it like this:

<merge
  ... />
  <Button
    ... />
  <EditText
    ... />
</merge>

Then in your CustomLayout constructor:

super(context, attrs);
Activity act = (Activity)context;
LayoutInflater inflater = act.getLayoutInflater();
View view = inflater.inflate (R.layout.custom_layout, this, true); // addView is not needed anymore
user
  • 86,916
  • 18
  • 197
  • 190
  • Thanks for your answer. It actually took a bit more to get this to work. When I first made the changes, I got the error "merge can be used only with a valid viewgroup root". To fix that, I removed the XML referring to the custom layout and instead created it in my code with **new CustomLayout (...)** followed by a call to **addView**. I'll update my post with the correction. – Peri Hartman Sep 22 '12 at 15:34