Главная страница
Образовательный портал Как узнать результаты егэ Стихи про летний лагерь 3агадки для детей
qrcode

Программирование под Android. Для профессионалов


Скачать 19.35 Mb.
НазваниеПрограммирование под Android. Для профессионалов
АнкорBrayn Khardi Bill Fillips - Programmirovanie po.
Дата23.05.2017
Размер19.35 Mb.
Формат файлаpdf
Имя файлаBrayn_Khardi_Bill_Fillips_-_Programmirovanie_po.pdf
оригинальный pdf просмотр
ТипДокументы
#21061
страница16 из 55
КаталогОбразовательный портал Как узнать результаты егэ Стихи про летний лагерь 3агадки для детей
Образовательный портал Как узнать результаты егэ Стихи про летний лагерь 3агадки для детей
1   ...   12   13   14   15   16   17   18   19   ...   55
Глава 7. UI-фрагменты и FragmentManager
Рис. 7.18. Жизненный цикл фрагмента (повторно)
Что произойдет, если добавить фрагмент в то время, как активность уже находится в состоянии остановки, приостановки или выполнения? В этом случае
Fragment-
Manager немедленно проводит фрагмент через все действия, необходимые для его согласования с состоянием активности. Например, при добавлении фрагмента в активность, уже находящуюся в состоянии выполнения, фрагмент получит вызовы onAttach(Activity)
, onCreate(Bundle)
, onCreateView(…)
, onActivityCreated(Bundle)
, onStart()
и затем onResume()
После того как состояние фрагмента будет согласовано с состоянием активности, объект
FragmentManager активности-хоста будет вызывать дальнейшие методы жизненного цикла приблизительно одновременно с получением соответствующих вызовов от ОС для синхронизации состояния фрагмента с состоянием активности.
Нет никаких гарантий относительно того, будут ли методы фрагмента вызваны до или после методов активности.
При использовании библиотеки поддержки в жизненном цикле фрагмента по- является одно отличие: если добавить фрагмент в
Activity.onCreate(…)
, то метод onActivityCreated(…)
не вызывается немедленно после
Activity.onCreate(…)

Для любознательных: разработка для Honeycomb, ICS, Jelly Bean и т. д.
161
Вместо этого он вызывается при выполнении
Activity.onStart()
. Почему? В SDK до Honeycomb невозможно вызвать onActivityCreated(…)
в правильный момент из
FragmentActivity
, поэтому метод вызывается при вызове следующего метода жизненного цикла. На практике это обычно ни на что не влияет; onStart()
все равно вызывается немедленно после
Activity.onCreate(…)
Почему все наши активности
используют фрагменты
С этого момента фрагменты будут использоваться во всех приложениях этой кни- ги — даже самых простых. На первый взгляд такое решение кажется чрезмерным: многие примеры, которые вам встретятся в следующих главах, могут быть записаны без фрагментов. Для создания пользовательских интерфейсов и управления ими можно обойтись активностями; возможно, это даже уменьшит объем кода.
Тем не менее мы полагаем, что вам стоит поскорее привыкнуть к паттерну, который наверняка пригодится вам в реальной работе.
Кто-то скажет, что лучше сначала написать простое приложение без фрагментов, а потом добавить их, когда потребуется (и если потребуется). Эта идея заложена в основу методологии экстремального программирования YAGNI. Сокращение
YAGNI означает «You Aren’t Gonna Need It» («Вам это не понадобится»); этот принцип убеждает вас не писать код, который, по вашему мнению, может пона- добиться позже. Почему? Потому что YAGNI. Возникает соблазн сказать YAGNI фрагментам.
К сожалению, добавление фрагментов в будущем может превратиться в мину за- медленного действия. Превратить активность в активность хоста UI-фрагмента несложно, но при этом возникает множество неприятных ловушек. Если одними интерфейсами будут управлять активности, а другими — фрагменты, это только усугубит ситуацию, потому что вам придется отслеживать эти бессмысленные раз- личия. Гораздо проще с самого начала написать код с использованием фрагментов и не возиться с его последующей переработкой, или же запоминать, какой стиль контроллера используется в каждой части вашего приложения.
Итак, в том, что касается фрагментов, мы применяем другой принцип: AUF, или
«Always Use Fragments» («Всегда используйте фрагменты»). Выбирая между ис- пользованием фрагмента и активности, вы потратите немало нервных клеток, а это просто не стоит того. AUF!
Для любознательных: разработка
для Honeycomb, ICS, Jelly Bean и т. д.
В этой главе вы узнали, как использовать библиотеку поддержки для включения фрагментов в проект с минимальной версией SDK ниже API уровня 11. Но если разработка предназначена исключительно для новых версий SDK, использовать

162
Глава 7. UI-фрагменты и FragmentManager библиотеку поддержки не обязательно. Вместо этого можно использовать «родные» классы фрагментов в стандартной библиотеке.
Чтобы использовать классы фрагментов стандартной библиотеки, необходимо внести в проект четыре изменения:

Задайте цель построения и минимальную версию SDK приложения на API уровня 11 и выше.

Субклассируйте класс
Activity стандартной библиотеки (
android.app.Activ- ity
) вместо
FragmentActivity
. В API уровня 11 и выше активности содержат готовую поддержку фрагментов.

Субклассируйте android.app.Fragment вместо android.support.v4.app.Fragment

Чтобы получить объект
FragmentManager
, используйте вызов getFragmentMan- ager()
вместо getSupportFragmentManager()

Макеты и виджеты
В этой главе мы поближе познакомимся с макетами и виджетами, а также включим хранение даты и статуса в CriminalIntent.
Обновление Crime
Откройте файл
Crime.java и добавьте два новых поля. Поле
Date представляет дату преступления, а поле mSolved
— признак того, было ли преступление раскрыто.
Листинг 8.1. Добавление полей в класс Crime (Crime.java)
public class Crime {
private UUID mId;
private String mTitle;
private Date mDate;
private boolean mSolved;
public Crime() {
mId = UUID.randomUUID();
mDate = new Date();
}
}
Инициализация переменной
Date конструктором
Date по умолчанию присваивает mDate текущую дату.
Затем сгенерируйте get
- и set
-методы для своих новых полей (
Source

Generate
Getters and
Setters...
).
Листинг 8.2. Сгенерированные get- и set-методы (Crime.java)
public class Crime {
public void setTitle(String title) {
mTitle = title;
}
8
продолжение


164
Глава 8. Макеты и виджеты
Листинг 8.2 (продолжение)
public Date getDate() {
return mDate;
}
public void setDate(Date date) {
mDate = date;
}
public boolean isSolved() {
return mSolved;
}
public void setSolved(boolean solved) {
mSolved = solved;
}
}
Наши следующие действия — обновление макета в fragment_crime.xml новыми вид- жетами и их связывание с виджетами в
CrimeFragment.java
Обновление макета
Вот как будет выглядеть представление
CrimeFragment к концу этой главы.
Рис. 8.1. CriminalIntent, эпизод 2
Чтобы добраться до этого экрана, мы добавим в макет
CrimeFragment четыре вид- жета: два виджета
TextView
,
Button и
CheckBox
Откройте файл fragment_crime.xml и внесите изменения, представленные в листин- ге 8.3. Возможно, вы получите ошибки отсутствия строковых ресурсов — вскоре мы их создадим.

Обновление Crime
165
Листинг 8.3. Добавление новых виджетов (fragment_crime.xml)

android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>

android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/crime_title_label"
/>
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:hint="@string/crime_title_hint"
/>

android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/crime_details_label"
/>

166
Глава 8. Макеты и виджеты
Листинг 8.4. Добавление строковых ресурсов (strings.xml)

CriminalIntent
CrimeActivity
Enter a title for this crime.
Title
Details
Solved?

Сохраните файлы и проверьте возможные опечатки.
Подключение виджетов
Виджет
CheckBox должен показывать, было ли преступление раскрыто. Изменение со- стояния
CheckBox также должно приводить к обновлению поля mSolved класса
Crime
От
Button пока что требуется только вывод даты из поля mDate
В файле
CrimeFragment.java добавьте две переменные экземпляра.
Листинг 8.5. Добавление переменных экземпляра для виджетов (CrimeFragment.java)
public class CrimeFragment extends Fragment {
private Crime mCrime;
private EditText mTitleField;
private Button mDateButton;
private CheckBox mSolvedCheckBox;
@Override public void onCreate(Bundle savedInstanceState) {
Выполните организацию импорта, чтобы разрешить ссылки на
DatePicker и
CheckBox
Затем в onCreateView(…)
получите ссылку на новую кнопку, задайте в тексте кнопки дату преступления и заблокируйте ее.
Листинг 8.6. Назначение текста Button (CrimeFragment.java)
@Override public View onCreateView(LayoutInflater inflater, ViewGroup parent,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_crime, parent, false);
mTitleField.addTextChangedListener(new TextWatcher() {
});
mDateButton = (Button)v.findViewById(R.id.crime_date);
mDateButton.setText(mCrime.getDate().toString());
mDateButton.setEnabled(false);
return v;
}

Подключение виджетов
167
Блокировка кнопки гарантирует, что она не будет реагировать на нажатия. Также при этом изменяется оформление кнопки, чтобы сообщить пользователю о забло- кированном состоянии. В главе 12 блокировка кнопки будет снята при назначении слушателя.
Теперь можно заняться
CheckBox
: мы получаем ссылку и назначаем слушателя, который будет обновлять поле mSolved объекта
Crime
Листинг 8.7. Назначение слушателя для изменений CheckBox (CrimeFragment.java)
mDateButton = (Button)v.findViewById(R.id.crime_date);
mDateButton.setText(mCrime.getDate().toString());
mDateButton.setEnabled(false);
mSolvedCheckBox = (CheckBox)v.findViewById(R.id.crime_solved);
mSolvedCheckBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
// Назначение флага раскрытия преступления
mCrime.setSolved(isChecked);
}
});
return v;
}
При импортировании интерфейса
OnCheckedChangeListener
Eclipse предложит вы- брать между интерфейсом, определенным в классе
CompoundButton
, и интерфейсом, определенным в классе
RadioGroup
. Выберите интерфейс
CompoundButton
;
CheckBox является субклассом
CompoundButton
Если вы используете функцию автозавершения, над методом onCheckedChanged(…)
может отображаться аннотация
@Override
, которой нет в листинге 8.7. На это от- личие можно не обращать внимания. Для методов, определенных в интерфейсах, аннотации
@Override не обязательны.
Запустите CriminalIntent. Переключите состояние
CheckBox и насладитесь видом заблокированной кнопки, на которой отображается текущая дата.
Подробнее об атрибутах макетов XML
Вернемся к некоторым атрибутам, добавленным в файле fragment_crime.xml
, и ответим на некоторые насущные вопросы по поводу виджетов и атрибутов.
Стили, темы и атрибуты тем
Стиль
(style) представляет собой ресурс XML, который содержит атрибуты, описывающие внешний вид и поведение виджета. Например, ниже приведен ресурс стиля, который настраивает виджет на использование увеличенного раз- мера текста.

168
Глава 8. Макеты и виджеты

Вы можете создавать собственные стили (мы займемся этим в главе 24). Они до- бавляются в файл стилей из каталога res/values/
, а ссылки на них в макетах выглядят так:
@style/my_own_style
Еще раз взгляните на виджеты
TextView из файла fragment_crime.xml
; каждый виджет имеет атрибут style
, который ссылается на стиль, созданный Android. С этим кон- кретным стилем виджеты
TextView выглядят как разделители списка, а берется он из
темы
приложения. Тема (theme) представляет собой набор стилей. Со структурной точки зрения тема сама является ресурсом стиля, атрибуты которого ссылаются на другие ресурсы стилей.
Android предоставляет платформенные темы, которые могут использоваться вашими приложениями. При создании CriminalIntent мастер предложил использовать тему приложения
Holo
Light with
Dark
Action
Bar
, и вы согласились.
Стиль из темы приложения можно применить к виджету при помощи ссылки на
атрибут темы
(theme attribute reference). Именно это мы делаем в файле frag- ment_crime.xml
, используя значение
?android:listSeparatorTextViewStyle
Ссылка на атрибут темы приказывает менеджеру ресурсов Android: «Перейди к теме приложения и найди в ней атрибут с именем listSeparatorTextViewStyle
. Этот атрибут указывает на другой ресурс стиля. Помести значение этого ресурса сюда».
Каждая тема Android включает атрибут с именем listSeparatorTextViewStyle
, но его определение зависит от оформления конкретной темы. Использование ссылки на атрибут темы гарантирует, что оформление виджетов
TextView будет соответ- ствовать оформлению вашего приложения.
О том, как работают стили и темы, более подробно рассказано в главе 24.
Плотность пикселов, dp и sp
В файле fragment_crime.xml значение атрибута margin задается в единицах dp
. Вы уже видели эти единицы в макетах; пришло время узнать, что они собой представляют.
Иногда значения атрибутов представления задаются в конкретных размерах (чаще всего в пикселах, но иногда в пунктах, миллиметрах или дюймах). Чаще всего этот способ используется для атрибутов размера текста, полей и отступов. Размер тек- ста равен высоте текста в пикселах на экране устройства. Поля задают расстояния между представлениями, а отступы задают расстояние между внешней границей представления и его содержимым.
Android автоматически масштабирует изображения для разных плотностей пикселов экрана, используя содержимое каталогов drawable-ldpi
, drawable-mdpi и drawable-hdpi
Но что произойдет, если ваши изображения масштабируются, а поля — нет? Или если пользователь выберет размер текста больше стандартного?

Подключение виджетов
169
Рис. 8.2. Использование единиц устройства на TextView (слева: MDPI; в середине: HDPI; справа: HDPI с большим текстом)
Для решения таких проблем в Android поддерживаются единицы, не зависящие от плотности пикселов; используя их, можно получить одинаковые размеры на экранах с разными плотностями. Android преобразует эти единицы в пикселы во время выпол- нения, так что вам не придется самостоятельно заниматься сложными вычислениями:

dp
(или dip
) — сокращение от «density-independent pixel» (пикселы, не завися- щие от плотности); произносится «дип». Обычно эти единицы используются для полей, отступов и всего остального, для чего обычно задаются размеры в пикселах. На экранах с более высокой плотностью единицы dp разворачива- ются в большее количество экранных пикселов. Одна единица dp всегда равна
1/160 дюйма на экране устройства. Размер будет одинаковым независимо от плотности пикселов.

sp
— сокращение от «scale-independent pixel» (пикселы, не зависящие от мас- штаба). Эти единицы, не зависящие от плотности пикселов устройства, также учитывают выбранный пользователем размер шрифта. Единицы sp почти всегда используются для назначения размера текста.

pt
, mm
, in
— масштабируемые единицы (как и dp
), позволяющие задавать размеры интерфейсных элементов в пунктах (1/72 дюйма), миллиметрах или дюймах.
Тем не менее мы не рекомендуем их использовать: не все устройства правильно настроены для правильного масштабирования этих устройств.
На практике и в этой книге почти исключительно используются только единицы dp и sp. Android преобразует эти значения в пикселы во время выполнения.
Рекомендации по проектированию интерфейсов Android
Для полей в нашем примере в листинге 8.3 используется значение
16dp
. Оно следует рекомендации по проектированию интерфейсов Android, известной как

170
1   ...   12   13   14   15   16   17   18   19   ...   55

перейти в каталог файлов

Образовательный портал Как узнать результаты егэ Стихи про летний лагерь 3агадки для детей

Образовательный портал Как узнать результаты егэ Стихи про летний лагерь 3агадки для детей