Освой Android играючи
/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
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 {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout mainLayout = 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 будет родителем для будущих элементов, которые мы будем добавлять или удалять:
<?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. Мы будем управлять ими программно.
<?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>
<?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. На скриншоте представлен этот вариант.
Получить доступ к дочерним элементам можно через методы getChildCount() и getChildAt().
Добавление элемента через анимацию (Android 4)