Создание составных Compound View объектов
Главная » Создание составных Compound View объектов

В процессе созданию фактически любого приложения разработчик использует бесконечное количество разных View элементов (TextView, GridView, ImageView и т.д.). Но часто возникает потребность в том, чтобы многократно использовать одну и ту же группу таких элементов в различных местах приложения. Можно конечно постоянно создавать их с нуля и загромождать программу однотипными кусками кода, но есть и другой способ. Довольно умным решением для этого случая является использование составных View элементов (Compound View), в которых сохранены все необходимые настройки и разметка нужной группы view элементов, и которые можно использовать сколько угодно раз в любой части программы. Согласитесь, это прилично экономит время и уменьшает количество нужного программе кода, ну и просто очень удобно. В этом уроке мы и научимся работать с такими составными view элементами.

В Android программировании, составным view (Compound View) элементом называется такой объект, которые состоит из группы view элементов. Также его иногда называют составным компонентом. 

Создаем новый проект, названия оставим по умолчанию, выбираем любимый нами Blank Activity. Минимальную версию ОС для запуска нашей программы выбираем Android 4.0

Теперь возьмемся за дело. Для созданию составного View объекта нужно создать отдельный класс, который будет управлять view элементами, входящими в Compound View. В папке res/layout создаем новый файл по имени sidespinner_view.xml и добавляем туда следующий код:

<merge xmlns:android="http://schemas.android.com/apk/res/android">
 <Button
 android:id="@+id/sidespinner_view_previous"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_toLeftOf="@+id/sidespinner_view_value"/>
 <TextView
 android:id="@+id/sidespinner_view_current_value"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:textSize="24sp" />
 <Button
 android:id="@+id/sidespinner_view_next"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content" />
</merge>

Далее нужно создать новый класс и связать его с выше созданным layout файлом и настроить созданным там кнопкам изображения стрелочек. Создаем новый класс по имени SideSpinner.java и добавим туда этот код:

import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.Button;
import android.widget.LinearLayout;

public class SideSpinner extends LinearLayout {

 private Button mPreviousButton;
 private Button mNextButton;

 public SideSpinner(Context context) {
 super(context);
 initializeViews(context);
 }

 public SideSpinner(Context context, AttributeSet attrs) {
 super(context, attrs);
 initializeViews(context);
 }

 @TargetApi(Build.VERSION_CODES.HONEYCOMB)
 public SideSpinner(Context context, AttributeSet attrs,int defStyle) {
 super(context, attrs, defStyle);
 initializeViews(context);
 }

 private void initializeViews(Context context) {
 LayoutInflater inflater = (LayoutInflater) context
 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 inflater.inflate(R.layout.sidespinner_view, this);
 }

 @Override
 protected void onFinishInflate() {
 super.onFinishInflate();

 //Настраиваем для обоих кнопок изображения.
 //Будем использовать стандартные изображения:
 mPreviousButton = (Button) this
 .findViewById(R.id.sidespinner_view_previous);
 mPreviousButton
 .setBackgroundResource(android.R.drawable.ic_media_previous);

 mNextButton = (Button)this
 .findViewById(R.id.sidespinner_view_next);
 mNextButton
 .setBackgroundResource(android.R.drawable.ic_media_next);
 }
}

Как видите, мы расширяем (extends) наш Compound View от LinearLayout. Это делается для того, чтобы предоставить Compound View объекту все свойства, которыми обладает LinearLayout. Когда мы добавим наш составной view в класс MainActivity, он будет восприниматься там как просто LinearLayout. Можно задавать расширение и от ViewGroup, но в нашем случае предпочтительнее сделать так, как сделали мы:). 

Теперь перейдем к файлу activity_main.xml и добавим туда наш Compound View:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 tools:context=".MainActivity">
 <home.study.SideSpinner
 android:id="@+id/sidespinner_fruits"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:orientation="horizontal"
 android:gravity="center"/>
</RelativeLayout>

Как видите, атрибуты, используемые в теге SideSpinner, это атрибуты обычного LinearLayout. По поводу строки home.study.SideSpinner. Это строка адреса к нашему классу SideSpinner и у вас она будет другой. Смотрите какая она у вас по структуре своего проекта:

Подсказка по строке адреса

Сейчас наше приложение выглядит примерно вот так:

Вид главного окна

Пока наши переключатели далеки от совершенства. Мы хотим сделать так, чтоб при переключении между ними сменялось слово, и его можно было выбрать нажатием. Самым простым способ придать нашей программе такое поведение, это добавить в класс SideSpinner новые методы, которые будут это делать. Перед этим добавьте пару переменных:

private CharSequence[] mSpinnerValues = null;
private int mSelectedIndex = -1;

А теперь добавляем необходимый код:

  public void setValues(CharSequence[] values) {
 mSpinnerValues = values;

 //Выбираем по умолчания первый элемент строкового массива:
 setSelectedIndex(0);
 }

 /**
 * Настраиваем выбранный index spinner-а.
 * @param index
 */
 public void setSelectedIndex(int index) {
 //Если для spinner ничего не выбрано, ничего не делаем:
 if (mSpinnerValues == null || mSpinnerValues.length == 0)
 return;

 //Если выбранный индекс не корректный, ничего не делаем:
 if (index < 0 || index >= mSpinnerValues.length)
 return;

 //Настраиваем корректный индекс и отображаем значение:
 mSelectedIndex = index;
 TextView currentValue;
 currentValue = (TextView)this
 .findViewById(R.id.sidespinner_view_current_value);
 currentValue.setText(mSpinnerValues[index]);

 //если показано первое значение, скрываем кнопку "Предыдущее":
 if (mSelectedIndex == 0)
 mPreviousButton.setVisibility(INVISIBLE);
 else
 mPreviousButton.setVisibility(VISIBLE);

 //Если показано последнее значение, скрываем кнопку "Далее":
 if (mSelectedIndex == mSpinnerValues.length - 1)
 mNextButton.setVisibility(INVISIBLE);
 else
 mNextButton.setVisibility(VISIBLE);
 }

 /**
 * @return выбранное значение spinner-а.
 */
 public CharSequence getSelectedValue() {
 //Если для spinner ничего не выбрано, устанавливаем пустую строку:
 if (mSpinnerValues == null || mSpinnerValues.length == 0)
 return "";

 //Если текущий index неправильный, устанавливаем пустую строку:
 if (mSelectedIndex < 0 || mSelectedIndex >= mSpinnerValues.length)
 return "";

 return mSpinnerValues[mSelectedIndex];
 }

 /**
 * Получаем выбранный index spinner-а.
 *
 * @return выбранный index spinner-а.
 */
 public int getSelectedIndex() {
 return mSelectedIndex;
 }

Когда все элементы из Compound View заполнены и готовы к использованию, вызывается метод onFinishInflate. Также этот метод отвечает за поведение кнопок "Вперед", "Назад". Добавляем в этот же класс SideSpinner.java следующий код, обновив код метода onFinishInflate (он уже создан нами выше):

 @Override
 protected void onFinishInflate() {
 super.onFinishInflate();

 //Настраиваем для обоих кнопок изображения.
 //Будем использовать стандартные изображения:
 mPreviousButton = (Button) this
 .findViewById(R.id.sidespinner_view_previous);
 mPreviousButton
 .setBackgroundResource(android.R.drawable.ic_media_previous);

 mNextButton = (Button)this
 .findViewById(R.id.sidespinner_view_next);
 mNextButton
 .setBackgroundResource(android.R.drawable.ic_media_next);

 
 super.onFinishInflate();

 //При нажатии кнопки "Назад", выбираем из списка предыдущее значение: 
 mPreviousButton = (Button) this
 .findViewById(R.id.sidespinner_view_previous);
 mPreviousButton
 .setBackgroundResource(android.R.drawable.ic_media_previous);

 mPreviousButton.setOnClickListener(new OnClickListener() {
 public void onClick(View view) {
 if (mSelectedIndex > 0) {
 int newSelectedIndex = mSelectedIndex - 1;
 setSelectedIndex(newSelectedIndex);
 }
 }
 });

 //Когда нажимается кнопка "Вперед", выбираем из списка следующее значение:
 mNextButton = (Button)this
 .findViewById(R.id.sidespinner_view_next);
 mNextButton
 .setBackgroundResource(android.R.drawable.ic_media_next);
 mNextButton.setOnClickListener(new OnClickListener() {
 public void onClick(View view) {
 if (mSpinnerValues != null
 && mSelectedIndex < mSpinnerValues.length - 1) {
 int newSelectedIndex = mSelectedIndex + 1;
 setSelectedIndex(newSelectedIndex);
 }
 }
 });

 //Выбираем первое значение по умолчанию:
 setSelectedIndex(0);
 }

Теперь нужно инициализировать переключатели в классе MainActivity.java и добавить строковый массив с словами, между которыми и будет происходить переключение при нажатии на кнопки. Обновим код метода onCreate в классе MainActivity.java:

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

 //Инициализируем SideSpinner:
 SideSpinner fruitsSpinner;
 fruitsSpinner = (SideSpinner)this.findViewById(R.id.sidespinner_fruits);

 CharSequence fruitList[] = { "Яблоко",
 "Апельсин",
 "Груша",
 "Виноград" };
 fruitsSpinner.setValues(fruitList);
 fruitsSpinner.setSelectedIndex(1);
 }

Если сейчас запустить наше приложение, то оно должно уже работать нормально и при нажатии на переключатели слово между ними будет меняться. Слово "Апельсин" будет выбрано по умолчанию:

Работает

Еще переключили

Здорово, да?:) Таким образом мы создали компонировку, соединение из 3 разных view элементов: двух кнопок Button и TextView, и все они взаимодействуют и работают совместно, образуя такой вот Compound View. Применяя эту технику, можно объединить любые элементы View. Надеюсь, вы почерпнули от этого урока много полезного, удачи!

Категория: Уроки программирования | Просмотров: 891 | Добавил: Oleg | Теги: сложные элементы, составные views, compound view, View | Рейтинг: 0.0/0
Всего комментариев: 0
avatar