In the this lesson we will:

- change layout-parameters for already existing screen components

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

 

We know how to create screen components and configure their location using LayoutParams. In this lesson we will find out how to change layout-parameters for already existing screen components.

We will change weight of the components. We will draw a SeekBar and two buttons. We will configure the space occupied by the buttons using weight parameter.

 

Let’s create a project:

Project name: P0181_DynamicLayout3
Build Target: Android 2.3.3
Application name: DynamicLayout3
Package name: ru.startandroid.develop.dynamiclayout3
Create Activity: MainActivity

 

Open main.xml and create the following screen:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <SeekBar
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:max="100"
        android:progress="50"
        android:layout_marginTop="20dp"
        android:id="@+id/sbWeight">
    </SeekBar>
    <LinearLayout
        android:id="@+id/linearLayout1"
        android:layout_width="match_parent"
        android:orientation="horizontal"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp">
        <Button
            android:layout_height="wrap_content"
            android:id="@+id/btn1"
            android:text="Button1"
            android:layout_weight="1"
            android:layout_width="wrap_content">
        </Button>
        <Button
            android:layout_height="wrap_content"
            android:id="@+id/btn2"
            android:text="Button2"
            android:layout_weight="1"
            android:layout_width="wrap_content">
        </Button>
    </LinearLayout>
</LinearLayout>

We are using a SeekBar component. It looks like a scrollbar and allows to specify a value from the range of values. This component has max and progress components. Max - the value which SeekBar returns when it is scrolled to maximum. Progress - is the current value of the bar. We will make maximum value = 100 and the current value will be on the half - 50;

Buttons have width by their content and their weight is both 1. They share the space of LinearLayout in which they are stretched equally.

The only thing  left is to write the code to make everything work. Open MainActivity.java, describe and find components and get access to their LayoutParams

public class MainActivity extends Activity {

  SeekBar sbWeight;
  Button btn1;
  Button btn2;

  LinearLayout.LayoutParams lParams1;
  LinearLayout.LayoutParams lParams2;

  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    sbWeight = (SeekBar) findViewById(R.id.sbWeight);

    btn1 = (Button) findViewById(R.id.btn1);
    btn2 = (Button) findViewById(R.id.btn2);

    lParams1 = (LinearLayout.LayoutParams) btn1.getLayoutParams();
    lParams2 = (LinearLayout.LayoutParams) btn2.getLayoutParams();
  }
}

We use getLayoutParams method to get LayoutParams of the component. This method returns basic ViewGroup.LayoutParams, but we need LinearLayout.LayoutParams, that’s why we do the casting. As a result - lParams1 and lParams2 are now LayoutParams for btn1 and btn2 components. That is when working with lParams1, for example, we influence btn1. We will use this now.

 

We will need a listener for our SeekBar, which will react to changes. We will make Activity do this. To do so we need to add implements OnSeekBarChangeListener to the class declaration:

public class MainActivity extends Activity implements OnSeekBarChangeListener {

 

We also have to add listener methods which Activity must now implement:

  @Override
  public void onProgressChanged(SeekBar seekBar, int progress,
      boolean fromUser) {

  }

  @Override
  public void onStartTrackingTouch(SeekBar seekBar) {

  }

  @Override
  public void onStopTrackingTouch(SeekBar seekBar) {

  }

 

Listener contains three methods. It is clear from the name that:

- onStartTrackingTouch triggers when we start dragging the bar
- onProgressChanged triggers every time when the value is changed
- onStopTrackingTouch triggers when we release the bar

We will be implementing onProgressChanged method so the changes will be visible when the bar is dragged.

  @Override
  public void onProgressChanged(SeekBar seekBar, int progress,
      boolean fromUser) {
    int leftValue = progress;
    int rightValue = seekBar.getMax() - progress;
    // configure the weight
    lParams1.weight = leftValue;
    lParams2.weight = rightValue;
    // write the value of variables into the buttons text
    btn1.setText(String.valueOf(leftValue));
    btn2.setText(String.valueOf(rightValue));
  }

 

 

leftValue variable - current value of the SeekBar, that is to the left of the bar

rightValue variable - value to the right, that is maximum value minus the current value.

We use these values as weight correspondingly. The more bar is to the left, the smaller leftValue and the bigger rightValue is, that means smaller btn1 width and greater btn2 width. And vice-versa.

 

Also to make it more obvious we will write variable values into the text of buttons.

And don’t forget that we have to assign the listener (Activity) to View-components whose events we need to process:

    setContentView(R.layout.main);

    sbWeight = (SeekBar) findViewById(R.id.sbWeight);
    sbWeight.setOnSeekBarChangeListener(this);

    btn1 = (Button) findViewById(R.id.btn1);

 

Save everything and run the application. We change button sizes by dragging the bar:

 

I guess it looks tellingly ) And there are only a few lines of code.

There is a small nuance. If you just write the code lParams1.weight = 1, the component will not change. We need to add the code: btn1.requestLayout(). In this case button will read Layout and redraw. This method is already invoked in setText, that’s why we do not invoke it explicitly.

Now we know quite a lot, and in the following lessons we will try to write first sensible application - a calculator.

Complete lesson code:

`

public class MainActivity extends Activity implements OnSeekBarChangeListener {

  SeekBar sbWeight;
  Button btn1;
  Button btn2;

  LinearLayout.LayoutParams lParams1;
  LinearLayout.LayoutParams lParams2;

  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    sbWeight = (SeekBar) findViewById(R.id.sbWeight);
    sbWeight.setOnSeekBarChangeListener(this);

    btn1 = (Button) findViewById(R.id.btn1);
    btn2 = (Button) findViewById(R.id.btn2);

    lParams1 = (LinearLayout.LayoutParams) btn1.getLayoutParams();
    lParams2 = (LinearLayout.LayoutParams) btn2.getLayoutParams();
  }

  @Override
  public void onProgressChanged(SeekBar seekBar, int progress,
      boolean fromUser) {
    int leftValue = progress;
    int rightValue = seekBar.getMax() - progress;
    // configure the weight
    lParams1.weight = leftValue;
    lParams2.weight = rightValue;
    // write the value of variables into the buttons text
    btn1.setText(String.valueOf(leftValue));
    btn2.setText(String.valueOf(rightValue));
  }

  @Override
  public void onStartTrackingTouch(SeekBar seekBar) {
  }

  @Override
  public void onStopTrackingTouch(SeekBar seekBar) {
  }
}

 

In the next lesson we will: 

- write a calculator application


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

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

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

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




Language