In this lesson we will:

- create layout programmatically, not using layout-files

Translated by Taras Leskiv (http://android-by-example.blogspot.com/) 

 

Up to this moment, we have been creating screens using layout-files. But we can do the same programmatically.

Let’s create a project:

 

Project name: P0161_DynamicLayout
Build Target: Android 2.3.3
Application name: DynamicLayout
Package name: ru.startandroid.develop.dinamiclayout
Create Activity: MainActivity

Open MainActivity.java and pay attention to the following line:

setContentView(R.layout.main);

 

Recall that in this line we specify that Activity will use layout-file main.xml as a screen. There is a different implementation of this method that takes as a parameter not a layout-file, but a View-element and makes it a root element. In layout-files a root element is usually LinearLayout, so we will use it too.

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // creating LinearLayout
        LinearLayout linLayout = new LinearLayout(this);
        // specifying vertical orientation
        linLayout.setOrientation(LinearLayout.VERTICAL);
        // creating LayoutParams  
        LayoutParams linLayoutParam = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 
        // set LinearLayout as a root element of the screen 
        setContentView(linLayout, linLayoutParam);
    }

 

Update the imports CTRL+SHIFT+O. Eclipse will ask which exactly LayoutParams we want to use. We will explore this in more detail. Let’s recall the theory about screens. A screen consists of the ViewGroup and View elements inside it.

ViewGroup classes we are already familiar with - LinearLayout, TableLayout, RelativeLayout and others. Every of these ViewGroup classes has LayoutParams inner class. The base class for these LayoutParams is ViewGroup.LayoutParams.

ViewGroup.LayoutParams has only two attributes: height and width. It’s subclass - ViewGroup.MarginLayoutParams inherits these two attributes and has four of its own: bottomMargin, leftMargin, rightMargin, topMargin. LinearLayout.LayoutParams class, which is by-turn a subclass of ViewGroup.MarginLayoutParams, inherits already 6 attributes from it and adds two of its own: gravity and weight.

So a LinearLayout object has inner class LinearLayout.LayoutParams with layout-attributes. And these attributes are distributed for all child Views and ViewGroups.

 

So View, which is inside LinearLayout has one set of layout-parameters:

 

View from RelativeLayout - has different:

 

There are some mutual elements as these ViewGroups have the same parents.

Let’s return to Eclipse, it still awaits our choice. Let’s use ViewGroup.LayoutParams base class

 

Let’s look throught the code. We create LinearLayout and specify vertical orientation. Then we create LayoutParams. The constructor takes two parameters: width and height. We set both as MATCH_PARENT. After this, setContentView method is invoked. LinearLayout and LayoutParams are passed to it as parameters. This means that LinearLayout with layout-attributes from LayoutParams will be the root element.

If we run the application now we will see nothing, as LinearLayout is transparent. Let’s start adding View-components to our LinearLayout.

        LayoutParams lpView = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        
        TextView tv = new TextView(this);
        tv.setText("TextView");
        tv.setLayoutParams(lpView);
        linLayout.addView(tv);
        
        Button btn = new Button(this);
        btn.setText("Button");
        linLayout.addView(btn, lpView);

 

We again create LayoutParams object with width = wrap_content and height = wrap_content attributes. Now if we assign this object to one of the Views, this View will have width and height defined by its content.

After this we create a TextView, update its text, set it previously created LayoutParams object and add it to LinearLayout using addView(View child) method.

The same with the Button - create, update text, and then use another implementation of addView(View child, ViewGroup.LayoutParams params) method, which simultaneously adds the Button to the LinearLayout and sets the Button the specified LayoutParams. Result will be the same as with the TextView, but instead of two lines of code we use only one.

Note that for two View objects I’ve used one LayoutParams object - lpView. And if I now change the properties of this objects, both views will change correspondingly.

Save and launch the application. We can see that the components have appeared on the screen. And we can see that their height and width is defined by their content (wrap_content).

 

lpView object has a basic type android.view.ViewGroup.LayoutParams. It means it will allow to configure only width and height. But for a View in the LinearLayout, for example, left margin or aligning by right edge are available. And if we want to apply them, we need to use LinearLayout.LayoutParams:

        LinearLayout.LayoutParams leftMarginParams = new LinearLayout.LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        leftMarginParams.leftMargin = 50;
        
        Button btn1 = new Button(this);
        btn1.setText("Button1");
        linLayout.addView(btn1, leftMarginParams);

Have a look at the code. We create an object of LinearLayout.LayoutParams type using the same constructor as for common LayoutParams, specifying width and height. Then we specify a left margin = 50. Margin here is specified in pixels. The algorithm is the same further: create an object, update the text and add it to the LinearLayout with setting LayoutParams.

Analogically, add the component with alignment:

        LinearLayout.LayoutParams rightGravityParams = new LinearLayout.LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        rightGravityParams.gravity = Gravity.RIGHT;
        
        Button btn2 = new Button(this);
        btn2.setText("Button2");
        linLayout.addView(btn2, rightGravityParams);

 

Save and launch. Button1 has a margin of 50px. And button2 is aligned by its right edge:

 

Most likely, this topic will not be absolutely clear at first. That’s why in the following two lessons we will revise the knowledge and will have some practice with adding elements on the screen and configuring them.

 

The complete lesson code:

public class MainActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // creating LinearLayout
        LinearLayout linLayout = new LinearLayout(this);
        // specifying vertical orientation
        linLayout.setOrientation(LinearLayout.VERTICAL);
        // creating LayoutParams  
        LayoutParams linLayoutParam = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 
        // set LinearLayout as a root element of the screen 
        setContentView(linLayout, linLayoutParam);
        
        LayoutParams lpView = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        
        TextView tv = new TextView(this);
        tv.setText("TextView");
        tv.setLayoutParams(lpView);
        linLayout.addView(tv);
        
        Button btn = new Button(this);
        btn.setText("Button");
        linLayout.addView(btn, lpView);

        
        LinearLayout.LayoutParams leftMarginParams = new LinearLayout.LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        leftMarginParams.leftMargin = 50;
        
        Button btn1 = new Button(this);
        btn1.setText("Button1");
        linLayout.addView(btn1, leftMarginParams);

        
        LinearLayout.LayoutParams rightGravityParams = new LinearLayout.LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        rightGravityParams.gravity = Gravity.RIGHT;
        
        Button btn2 = new Button(this);
        btn2.setText("Button2");
        linLayout.addView(btn2, rightGravityParams);
    }
}

 

In the next lesson we will: 

- add components on the screen while application is running.

 


Присоединяйтесь к нам в Telegram:

- в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.

- в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Compose, Kotlin, RxJava, Dagger, Тестирование, Performance 

- ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня




Language