
- •Глава 4
- •ViewGroup. Правильное использование разметки чрезвычайно важно при
- •Знакомство с Представлениями
- •ViewGroup — это производный от View класс, спроектированный для
- •Знакомство с менеджерами компоновки
- •Использование разметки
- •Оптимизация разметки
- •Изменение существующих Представлений
- •5. Чтобы отобразить лист, переопределите метод onDraw и нарисуйте
- •Создание нового графического интерфейса
- •Внимание
- •10 Dp и такой же толщины контур. Результат представлен на рис. 4.3.
- •LayerDrawable
- •StateListDrawable
- •LevelListDrawable
- •ImageView.SetImageLevel(5);
- •Ресурс NinePatch
- •800 480 И 854 480). Точно так же физические размеры экрана начинаются
5. Чтобы отобразить лист, переопределите метод onDraw и нарисуйте
изображение, используя объекты Paint из пункта 4. Вызовите метод
onDraw из родительского класса и позвольте ему нарисовать текст,
как он это обычно делает.
@Override
public void onDraw(Canvas canvas) {
// Фоновый цвет для листа
canvas.drawColor(paperColor);
// Нарисуйте направляющие линии
canvas.drawLine(0, 0, getMeasuredHeight(), 0, linePaint);
canvas.drawLine(0, getMeasuredHeight(),
getMeasuredWidth(), getMeasuredHeight(),
linePaint);
// Нарисуйте кромку
144 бет
canvas.drawLine(margin, 0, margin, getMeasuredHeight(), marginPaint);
// Переместите текст в сторону от кромки
canvas.save();
canvas.translate(margin, 0);
// Используйте TextView для вывода текста.
super.onDraw(canvas);
canvas.restore();
}
6. На этом реализация TodoListItemView завершена. Чтобы использо-
вать ее внутри Активности ToDoList, необходимо добавить соответ-
ствующий элемент в новую разметку, после чего передать эту разметку
в конструктор объекта ArrayAdapter.
Начните с создания нового ресурса todolist_item.xml в каталоге
res/layout. В нем указано, каким образом должен отображаться каждый
элемент списка. В данном примере разметка должна состоять из един-
ственного элемента TodoListItemView, заполняющего все доступное
пространство.
<?xml version="1.0" encoding="utf-8"?>
<com.paad.todolist.TodoListItemView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:scrollbars="vertical"
android:textColor="@color/notepad_text"
android:fadingEdge="vertical"
/>
7. Теперь откройте класс Активности ToDoList. В завершение необхо-
димо изменить параметры, передаваемые в ArrayAdapter внутри ме-
тода onCreate. Вместо ссылки, указывающей на стандартный ресурс
android.R.layout.simple_list_item_1, вставьте ссылку на новую
разметку R.layout.todolist_item, созданную вами на шаге 6.
final ArrayList<String> todoItems = new ArrayList<String>();
int resID = R.layout.todolist_item;
final ArrayAdapter<String> aa = new ArrayAdapter<String>(this, resID,
todoItems);
myListView.setAdapter(aa);
Создание составных элементов управления
Составные элементы управления — это полноценные, пригодные для
многократного использования Представления, которые содержат несколько
дочерних компонентов, скомпонованных и связанных друг с другом.
При создании составного элемента управления необходимо опреде-
лить разметку, внешний вид и связи между Представлениями, которые он
145 бет
содержит. Такие элементы получаются в результате наследования клас-
са ViewGroup (или его производных, например разметки). Чтобы создать
новый составной элемент управления, выберите класс разметки, который
больше всего подходит для позиционирования дочерних компонентов, и на-
следуйте его, как показано в листинге 4.6.
Листинг 4.6. Создание составного элемента управления
public class MyCompoundView extends LinearLayout {
public MyCompoundView(Context context) {
super(context);
}
public MyCompoundView(Context context, AttributeSet attrs) {
super(context, attrs);
}
}
Как и в случае с Активностями, при проектировании разметки для со-
ставных Представлений лучше всего использовать внешний ресурс. В листин-
ге 4.7 показан пример описания разметки в формате XML для элемента,
содержащего два Представления: поле ввода EditText и кнопку Button, которая
это поле очищает.
Листинг 4.7. Ресурс с разметкой для составного Представления
<?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">
<EditText
android:id="@+id/editText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<Button
android:id="@+id/clearButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Clear"
/>
</LinearLayout>
Чтобы применить эту разметку, переопределите конструктор нового
Представления, добавив в него вызов метода inflate, который принадлежит
системному Сервису LayoutInflate. Данный метод принимает в качестве па-
раметра ресурс с разметкой и возвращает ≪наполненное≫ Представление.
В случаях, подобных описанному выше, когда возвращаемое Пред-
ставление должно иметь созданный вами класс, можно передать родитель-
ский элемент и автоматически прикрепить к нему результат, как показано
ниже.
146 бет
В листинге 4.8 представлен класс ClearableEditText, в конструкторе
которого происходит наполнение ресурса с разметкой, созданного ранее,
и получение ссылок на каждое Представление, которое он содержит. При этом
вызывается метод hookupButton, используемый для подключения функции
≪очистки текста≫, срабатывающей при нажатии кнопки.
Листинг 4.8. Создание составного Представления
public class ClearableEditText extends LinearLayout {
EditText editText;
Button clearButton;
public ClearableEditText(Context context) {
super(context);
// Наполните Представление из ресурса с разметкой.
String infService = Context.LAYOUT_INFLATER_SERVICE;
LayoutInflater li;
li = (LayoutInflater)getContext().getSystemService(infService);
li.inflate(R.layout.clearable_edit_text, this, true);
// Получите ссылки на дочерние элементы.
editText = (EditText)findViewById(R.id.editText);
clearButton = (Button)findViewById(R.id.clearButton);
// Подключите функциональность
hookupButton();
}
}
Если вы предпочитаете создавать разметку в коде программы, можете
сделать это таким же образом, как и в случае с Активностью. В листинге 4.9
показан переопределенный конструктор ClearableEditText, в котором соз-
дается пользовательский интерфейс, аналогичный тому, что был описан
в формате XML в предыдущем листинге.
Листинг 4.9. Создание разметки для составного Представления в коде
программы
public ClearableEditText(Context context) {
super(context);
// Сделайте разметку вертикальной
setOrientation(LinearLayout.VERTICAL);
// Создайте дочерние элементы управления.
editText = new EditText(getContext());
clearButton = new Button(getContext());
clearButton.setText("Clear");
// Расположите их внутри составного элемента.
int lHeight = LayoutParams.WRAP_CONTENT;
147 бет
int lWidth = LayoutParams.FILL_PARENT;
addView(editText, new LinearLayout.LayoutParams(lWidth, lHeight));
addView(clearButton, new LinearLayout.LayoutParams(lWidth, lHeight));
// Подключите функциональность
hookupButton();
}
Создав разметку для Представления, можно подключить обработчики
событий для каждого дочернего элемента, чтобы обеспечить нужную функ-
циональность. В представленном ниже фрагменте наполняется кодом метод
hookupButton — он отвечает за очистку текста в элементе EditText при
нажатии кнопки:
private void hookupButton() {
clearButton.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
editText.setText("");
}
});
}
Создание нестандартных Представлений
Создавая полностью новые Представления, вы получаете полный контроль
над формированием внешнего вида и поведением своих программ. Можно
создавать пользовательские интерфейсы, которые идеально подходят под
нужды пользователей. Чтобы выполнить новый элемент с чистого листа, не-
обходимо наследовать один из двух классов — либо View, либо SurfaceView.
Класс View предоставляет объект Canvas, который помимо классов Paint
содержит методы для рисования. Используйте их для создания визуального
интерфейса на основе растровой графики. Затем вы можете переопреде-
лить пользовательские события, такие как нажатия клавиш или касания
сенсорного экрана, чтобы обеспечить необходимую интерактивность. Если
приложение не должно поддерживать чрезвычайно быструю перерисовку
и трехмерную графику, базовый класс View подойдет в качестве мощного
и легковесного решения.
Класс SurfaceView предоставляет объект Surface, который поддерживает
рисование в фоновом потоке и дает возможность использовать OpenGL для
трехмерной графики. Это отличный вариант для насыщенных графикой эле-
ментов, которые нуждаются в частых обновлениях или должны отображать
сложную графическую информацию, как в случае с играми и трехмерной
визуализацией.
Далее вы познакомитесь с двумерными элементами управления, осно-
ванными на классе View. Больше информации о классе SurfaceView и о не-
которых продвинутых возможностях Canvas, доступных в Android, пред-
ставлено в главе 15.
148 бет