Главная » Разработка для Android » Задание размеров для вашего элемента

0

Если ваш элемент не может идеально вписаться в площадь 100 ? 100 пик- селов, вам необходимо переопределить обработчик onMeasure.

Данный  метод вызывается в момент, когда родительское  Представле- ние размещает  внутри  себя дочерние  элементы.  Оно как бы спрашивает:

«Cколько места вы собираетесь использовать?» — и передает два параметра: widthMeasureSpec и heightMeasureSpec. Они определяют доступное для эле- мента пространство,  а также некоторые метаданные, описывающие его.

Вместо того чтобы возвращать  результат, необходимо передать высоту и ширину Представления в метод setMeasuredDimension.

В листинге  4.12 показано,  как переопределить обработчик  onMeasure. Обратите внимание на вызовы локальных методов-заглушек calculateHeight и calculateWidth. Они будут использоваться для декодирования значений widthHeightSpec и heightMeasureSpec, а также для вычисления предпо- чтительных высоты и ширины.

Листинг 4.12. Определение размеров Представления

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

int measuredHeight = measureHeight(heightMeasureSpec);

int measuredWidth = measureWidth(widthMeasureSpec);

setMeasuredDimension(measuredHeight, measuredWidth);

}

private int measureHeight(int measureSpec) {

// Верните измеренную высоту виджета.

}

private int measureWidth(int measureSpec) {

// Верните измеренную ширину виджета.

}

Параметры widthMeasureSpec и heightMeasureSpec, описывающие гра- ницы элемента, из соображений эффективности передаются в виде целочис- ленных значений. Прежде чем их использовать,  они должны быть декоди- рованы с помощью статических методов getMode и getSize, принадлежащих классу MeasureSpec:

int specMode = MeasureSpec.getMode(measureSpec);

int specSize = MeasureSpec.getSize(measureSpec);

В зависимости от режима mode, свойство size представляет собой либо максимальное пространство, доступное для элемента управления (при режи- ме AT_MOST), либо точные размеры области, которую займет Представление (при режиме EXACTLY). Если режим был установлен в UNSPECIFIED, ваш элемент не будет знать, какое именно значение описывает свойство size.

Задавая свойству mode значение EXACTLY, родительский элемент де- кларирует,  что Представление будет помещено именно в ту область, размер которой  был указан. В режиме  AT_MOST родительский элемент  спра- шивает Представление, какой размер оно хочет занять, предлагая  при этом определенные границы, за которые оно не может выйти. Часто бывает, что в обоих случаях возвращаемые значения  идентичны.

Как бы то ни было, вы должны рассматривать эти ограничения как аб- солютные. Иногда  целесообразно возвращать  размеры, выходящие  за эти

рамки. В таких случаях родительский элемент сам выбирает, как поступать с Представлением, используя обрезание или прокрутку.

В листинге 4.13 показана типичная реализация управления размерами

Представления.

Листинг 4.13. Типичная реализация управления размерами  Представления

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

int measuredHeight = measureHeight(heightMeasureSpec);

int measuredWidth = measureWidth(widthMeasureSpec);

setMeasuredDimension(measuredHeight, measuredWidth);

}

private int measureHeight(int measureSpec) {

int specMode = MeasureSpec.getMode(measureSpec);

int specSize = MeasureSpec.getSize(measureSpec);

// Размер по умолчанию, если ограничения не были установлены. int result = 500;

if (specMode == MeasureSpec.AT_MOST) {

// Рассчитайте идеальный размер вашего

// элемента в рамках максимальных значений.

// Если ваш элемент заполняет все доступное

// пространство, верните внешнюю границу. result = specSize;

} else if (specMode == MeasureSpec.EXACTLY) {

// Если ваш элемент может поместиться внутри этих границ, верните это значение.

result = specSize;

}

return result;

}

private int measureWidth(int measureSpec) {

int specMode = MeasureSpec.getMode(measureSpec);

int specSize = MeasureSpec.getSize(measureSpec);

// Размер по умолчанию, если ограничения не были установлены. int result = 500;

if (specMode == MeasureSpec.AT_MOST) {

// Рассчитайте идеальный размер вашего

// элемента в рамках максимальных значений.

// Если ваш элемент заполняет все доступное

// пространство, верните внешнюю границу. result = specSize;

} else if (specMode == MeasureSpec.EXACTLY) {

// Если ваш элемент может поместиться внутри этих границ, верните это значение.

result = specSize;

}

return result;

}

Источник: Майер P. Android 2 : программирование приложений для планшетных компьютеров и смартфонов : [пер. с англ. ] / Рето Майер. — М. : Эксмо, 2011. — 672 с. — (Мировой компьютерный бестселлер).

По теме:

  • Комментарии