Сайт разработчика Александр Климова

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

Программное добавление и удаление виджета

Добавляем виджет
Удаляем виджет

Обычно мы размещаем виджеты через XML. Но можно это делать и программно. Такой подход используется при динамическом размещении, когда неизвестно, сколько элементов должно быть на экране.

Добавляем виджет

Допустим у нас есть простейшая разметка.


<?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"
    >
<LinearLayout
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/mainlayout"
    />
<TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    />
</LinearLayout>

Пустая компоновка LinearLayout с идентификатором mainlayout не содержит вложенных виджетов. Через метод addView(view) класса LinearLayout мы можем добавить нужный нам элемент.


public class AndroidAddViewActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
        
    LinearLayout mainLayout = (LinearLayout)findViewById(R.id.mainlayout);
        
    // Добавляем новый ImageView
    ImageView imageView = new ImageView(MainActivity.this);
    imageView.setImageResource(R.drawable.icon);
    LayoutParams imageViewLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    imageView.setLayoutParams(imageViewLayoutParams);
  
    mainLayout.addView(imageView);
}

Удаляем виджет

Существует и обратный метод для удаления вида - removeView(), а также метод removeAllViews(), удаляющий все дочерние элементы родителя. Рассмотрим следующий пример. Создадим разметку, где компонент LinearLayout с идентификатором master будет родителем для будущих элементов, которые мы будем добавлять или удалять:

activity_main.xml


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <CheckBox
            android:id="@+id/enlayer1"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="Enable Layer 1" />

        <CheckBox
            android:id="@+id/enlayer2"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="Enable Layer 2" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/master"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" />

</LinearLayout>

Создадим пару дополнительных макетов, которые будет дочерними элементами для FrameLayout. Мы будем управлять ими программно.

layer1.xml


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Layer 1" />

    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="EditText" />

</LinearLayout>

layer2.xml


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="Layer 2" />

    <CheckBox
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="CheckBox A" />

    <CheckBox
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="CheckBox B" />

    <CheckBox
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="CheckBox C" />

</LinearLayout>

Напишем код, который будет добавлять или удалять компоновки через флажки.


public class MainActivity extends Activity {

	LinearLayout mainLayer;
	View layer1, layer2;
	CheckBox enableLayer1, enableLayer2, enableLayer3;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		enableLayer1 = (CheckBox) findViewById(R.id.enlayer1);
		enableLayer2 = (CheckBox) findViewById(R.id.enlayer2);

		mainLayer = (LinearLayout) findViewById(R.id.master);

		LayoutInflater inflater = getLayoutInflater();
		layer1 = inflater.inflate(R.layout.layer1, null);
		layer2 = inflater.inflate(R.layout.layer2, null);

		enableLayer1.setOnCheckedChangeListener(enableLayer1ChangeListener);
		enableLayer2.setOnCheckedChangeListener(enableLayer2ChangeListener);
	}

	CheckBox.OnCheckedChangeListener enableLayer1ChangeListener = new CheckBox.OnCheckedChangeListener() {

		@Override
		public void onCheckedChanged(CompoundButton buttonView,
				boolean isChecked) {
			if (isChecked) {
				mainLayer.addView(layer1);
			} else {
				mainLayer.removeView(layer1);
			}
		}
	};

	CheckBox.OnCheckedChangeListener enableLayer2ChangeListener = new CheckBox.OnCheckedChangeListener() {

		@Override
		public void onCheckedChanged(CompoundButton buttonView,
				boolean isChecked) {
			if (isChecked) {
				mainLayer.addView(layer2);
			} else {
				mainLayer.removeView(layer2);
			}
		}
	};
}

Обратите внимание, что добавление идёт в том порядке, как мы отмечаем флажки. Если мы отметим флажком второй CheckBox, то сначала на экране появится блок с компоновкой layer2.xml, а уже ниже компоновка layer1.xml. На скриншоте представлен этот вариант.

addView

Получить доступ к дочерним элементам можно через методы getChildCount() и getChildAt().

Дополнительное чтение

Добавление элемента через анимацию (Android 4)

Реклама