How to create a custom View's layout programmatically?

XåpplI'-I0llwlg'I  - picture XåpplI'-I0llwlg'I - · Jan 2, 2013 · Viewed 39k times · Source

In an Activity, you can create a LinearLayout programmatically in the following way:

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

    LinearLayout ll = new LinearLayout(this);
    ll.setOrientation(LinearLayout.VERTICAL);
    ll.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

    TextView tv1 = new TextView(this);
    tv1.setText("HELLO");
    ll.addView(tv1);

    TextView tv2 = new TextView(this);
    tv2.setText("WORLD");
    ll.addView(tv2);

    setContentView(ll);
}

How do you do the same inside a custom View subclass? There are no setContentView or onCreate methods...

Answer

XåpplI'-I0llwlg'I  - picture XåpplI'-I0llwlg'I - · Jan 2, 2013

Okay, I discovered one way of doing it. Basically, instead of subclassing the View class directly, you need to subclass the top-most class that you would normally define in XML. For example, if your custom View needs a LinearLayout as its top-most class, then your custom View should simply subclass LinearLayout.

For example:

public class MyCustomView extends LinearLayout
{
    public MyCustomView(Context context, AttributeSet attrs)
    {
        super(context, attrs);

        setOrientation(LinearLayout.VERTICAL);
        setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

        TextView tv1 = new TextView(context);
        tv1.setText("HELLO");
        addView(tv1);

        TextView tv2 = new TextView(context);
        tv2.setText("WORLD");
        addView(tv2);
    }
}

Is subclassing LinearLayout a "hack"? Not as far as I can see. Some official View subclasses do the same, like NumberPicker and SearchView (even though they inflate their layouts from XML).

Upon reflection, it's actually a pretty obvious answer.