Главная страница
Образовательный портал Как узнать результаты егэ Стихи про летний лагерь 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
страница12 из 55
КаталогОбразовательный портал Как узнать результаты егэ Стихи про летний лагерь 3агадки для детей
Образовательный портал Как узнать результаты егэ Стихи про летний лагерь 3агадки для детей
1   ...   8   9   10   11   12   13   14   15   ...   55
Глава 5. Вторая активность
Интенты представляют собой многоцелевые средства передачи информации, а класс
Intent предоставляет разные конструкторы в зависимости от того, для чего должен использоваться интент.
В данном случае интент сообщает
ActivityManager
, какую активность следует за- пустить, поэтому мы используем следующий конструктор:
public Intent(Context packageContext, Class cls)
Объект
Class задает активность, которая должна быть запущена
ActivityManager
Объект
Context сообщает
ActivityManager
, в каком пакете находится объект
Class
ОС Android
Рис. 5.9. Интент: передача ActivityManager информации о том, что нужно сделать
В слушателе mCheatButton создайте объект
Intent
, включающий класс
CheatActiv- ity
, а затем передайте его при вызове startActivity(Intent)
(листинг 5.8).
Листинг 5.8. Запуск CheatActivity (QuizActivity.java)
mCheatButton = (Button)findViewById(R.id.cheat_button);
mCheatButton.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
Intent i = new Intent(QuizActivity.this, CheatActivity.class);
startActivity(i);
}
});
updateQuestion();
}
Прежде чем запускать активность,
ActivityManager ищет в манифесте пакета объ- явление с именем, соответствующим заданному объекту
Class
. Если такое объ- явление будет найдено, активность запускается — все хорошо. Если объявление не найдено, выдается исключение
ActivityNotFoundException
. Вот почему все активности должны объявляться в манифесте.

Передача данных между активностями
115
Интенты явные и неявные
При создании объекта
Intent с объектом
Class и
Context вы создаете явный (explicit) интент. Явные интенты используются для запуска активностей в приложениях.
Может показаться странным, что две активности внутри приложения должны вза- имодействовать через компонент
ActivityManager
, находящийся вне приложения.
Тем не менее такая схема позволяет активности одного приложения легко работать с активностью другого приложения.
Когда активность в вашем приложении должна запустить активность в другом при- ложении, вы создаете неявный (implicit) интент. Использование неявных интентов рассматривается в главе 21.
Запустите GeoQuiz. Нажмите кнопку
Cheat!
; на экране появляется экземпляр новой активности.
Теперь нажмите кнопку
Back
. Активность
CheatActivity уничтожается, а вы воз- вращаетесь к
QuizActivity
Передача данных между активностями
Итак, в нашем приложении действуют активности
QuizActivity и
CheatActivity
, и мы можем подумать о передаче данных между ними. На рис. 5.10 показано, какие данные будут передаваться между двумя активностями.
Пользователь подсмотрел ответ?
Ответ равен «True»?
Рис. 5.10. Обмен данными между QuizActivity и CheatActivity
QuizActivity передает
CheatActivity ответ на текущий вопрос при запуске
CheatActivity
Когда пользователь нажимает кнопку
Back
, чтобы вернуться к
QuizActivity
, экзем- пляр
CheatActivity уничтожается. В последний момент он передает
QuizActivity информацию о том, подсмотрел ли пользователь правильный ответ.
Начнем с передачи данных от
QuizActivity к
CheatActivity

116
Глава 5. Вторая активность
Дополнения интентов
Чтобы сообщить
CheatActivity ответ на текущий вопрос, мы будем передавать значение mAnswerKey[mCurrentIndex].isTrueQuestion();
Значение будет передаваться в виде дополнения (extra) объекта
Intent
, передава- емого startActivity(Intent)
Дополнения представляют собой произвольные данные, которые вызывающая активность может передать вместе с интентом. ОС направляет интент активности получателю, которая обращается к дополнению и извлекает данные.
ОС Android
Рис. 5.11. Дополнения интентов: взаимодействие с другими активностями
Дополнение представляет собой пару «ключ-значение» наподобие той, кото- рая использовалась для сохранения значения mCurrentIndex в
QuizActivity.
onSaveInstanceState(Bundle)
Для включения дополнений в интент используется метод
Intent.putExtra(…)
— а точнее, метод public Intent putExtra(String name, boolean value)
Метод
Intent.putExtra(…)
существует в нескольких разновидностях, но он всегда получает два аргумента. В первом аргументе всегда передается ключ
String
, а во втором — значение того или иного типа.
Добавьте в
CheatActivity.java ключ для дополнения.
Листинг 5.9. Добавление константы (CheatActivity.java)
public class CheatActivity extends Activity {
public static final String EXTRA_ANSWER_IS_TRUE =
"com.bignerdranch.android.geoquiz.answer_is_true";

Передача данных между активностями
117
Активность может запускаться из нескольких разных мест, поэтому ключи для до- полнений должны определяться в активностях, которые читают и используют их.
Как видно из листинга 5.9, уточнение дополнения именем пакета предотвращает конфликты имен с дополнениями других приложений.
Вернемся к
QuizActivity и включим дополнение в интент.
Листинг 5.10. Включение дополнения в интент (QuizActivity.java)
mCheatButton.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
Intent i = new Intent(QuizActivity.this, CheatActivity.class);
boolean answerIsTrue = mAnswerKey[mCurrentIndex].isTrueQuestion();
i.putExtra(CheatActivity.EXTRA_ANSWER_IS_TRUE, answerIsTrue);
startActivity(i);
}
});
updateQuestion();
}
В нашей ситуации достаточно одного дополнения, но при необходимости можно добавить в
Intent несколько дополнений.
Для чтения значения из дополнения используется метод public boolean getBooleanExtra(String name, boolean defaultValue)
Первый аргумент getBooleanExtra(…)
содержит имя дополнения, а второй — ответ по умолчанию, если ключ не найден.
В
CheatActivity прочитайте значение из дополнения и сохраните его в переменной.
Листинг 5.11. Использование дополнения (CheatActivity.java)
public class CheatActivity extends Activity {
private boolean mAnswerIsTrue;
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cheat);
mAnswerIsTrue = getIntent().getBooleanExtra(EXTRA_ANSWER_IS_TRUE, false);
}
}
Обратите внимание:
Activity.getIntent()
возвращает объект
Intent
, который был передан в startActivity(Intent)
Наконец, добавьте в
CheatActivity код, обеспечивающий использование прочитан- ного значения в виджете
TextView ответа и кнопке
Show
Answer

118
Глава 5. Вторая активность
Листинг 5.12. Добавление функциональности подсматривания ответов (CheatActivity.java)
public class CheatActivity extends Activity {
private boolean mAnswerIsTrue;
private TextView mAnswerTextView;
private Button mShowAnswer;
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cheat);
mAnswerIsTrue = getIntent().getBooleanExtra(EXTRA_ANSWER_IS_TRUE, false);
mAnswerTextView = (TextView)findViewById(R.id.answerTextView);
mShowAnswer = (Button)findViewById(R.id.showAnswerButton);
mShowAnswer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mAnswerIsTrue) {
mAnswerTextView.setText(R.string.true_button);
} else {
mAnswerTextView.setText(R.string.false_button);
}
}
});
}
}
Код достаточно тривиален: мы задаем текст
TextView при помощи метода
TextView.
setText(int)
. Метод
TextView.setText(…)
существует в нескольких вариантах; здесь используется вариант, получающий идентификатор строкового ресурса.
Запустите приложение GeoQuiz. Нажмите кнопку
Cheat!
, чтобы перейти к
CheatAc- tivity
. Затем нажмите кнопку
Show
Answer
, чтобы открыть ответ на текущий вопрос.
Получение результата от дочерней активности
В текущей версии приложения пользователь может беспрепятственно жульничать.
Сейчас мы исправим этот недостаток; для этого
CheatActivity будет сообщать
QuizActivity
, подсмотрел ли пользователь ответ.
Чтобы получить информацию от дочерней активности, вызовите следующий метод
Activity
:
public void startActivityForResult(Intent intent, int requestCode)
Первый параметр содержит тот же интент, что и прежде. Во втором параметре содер- жится код запроса — определяемое пользователем целое число, которое передается дочерней активности, а затем принимается обратно родителем. Оно используется тогда, когда активность запускает сразу несколько типов дочерних активностей и ей необходимо определить, кто из потомков возвращает данные.

Передача данных между активностями
119
В классе
QuizActivity измените слушателя mCheatButton и включите в него вызов startActivityForResult(Intent,
int)
Листинг 5.13. Вызов startActivityForResult(…) (QuizActivity.java)
mCheatButton.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
Intent i = new Intent(QuizActivity.this, CheatActivity.class);
boolean answerIsTrue = mAnswerKey[mCurrentIndex].isTrueQuestion();
i.putExtra(CheatActivity.EXTRA_ANSWER_IS_TRUE, answerIsTrue);
startActivity(i);
startActivityForResult(i, 0);
}
});
updateQuestion();
}
QuizActivity всегда запускает дочерние активности только одного типа. Значение второго обязательного параметра в этом случае несущественно, поэтому мы будем передавать 0.
Передача результата
Существует два метода, которые могут вызываться в дочерней активности для возвращения данных родителю:
public final void setResult(int resultCode)
public final void setResult(int resultCode, Intent data)
Как правило, resultCode содержит одну из двух предопределенных констант:
Activ- ity.RESULT_OK
или
Activity.RESULT_CANCELED
. (Также можно использовать другую константу
RESULT_FIRST_USER
как смещение при определении собственных кодов результатов.)
Назначение кода результата полезно в том случае, когда родитель должен выпол- нить разные действия в зависимости от того, как завершилась дочерняя активность.
Например, если в дочерней активности присутствуют кнопки
OK
и
Cancel
, то дочерняя активность может назначать разные коды результата в зависимости от того, какая кнопка была нажата. Родительская активность будет выбирать разные варианты действий в зависимости от полученного кода.
Вызов setResult(…)
не является обязательным для дочерней активности. Если вам не нужно различать результаты или получать произвольные данные по интенту, просто разрешите ОС отправить код результата по умолчанию. Код результата всегда возвращается родителю, если дочерняя активность была запущена методом startActivityForResult(…)
. Если метод setResult(…)
не вызывался, то при нажатии пользователем кнопки
Back родитель получит код
Activity.RESULT_CANCELED

120
Глава 5. Вторая активность
Возвращение интента
В нашей реализации дочерняя активность должна вернуть
QuizActivity некоторые данные. Соответственно, мы создадим объект
Intent
, поместим в него дополне- ние, а затем вызовем
Activity.setResult(int,
Intent)
для передачи этих данных
QuizActivity
Ранее в приложении была определена константа для дополнения, получаемого
CheatActivity внутри
CheatActivity
. То же самое следует сделать для нового до- полнения, которое
CheatActivity отправляет
QuizActivity
. Это объясняется тем, что входящие и исходящие дополнения определяют интерфейс
CheatActivity
. Если вы захотите использовать
CheatActivity в другом месте приложения, вы будете ссылаться на константы, определенные исключительно в
CheatActivity
Добавьте в
CheatActivity константу для ключа дополнения и закрытый метод, который создает интент, помещает в него дополнение и назначает код результата.
Затем включите вызов этого метода в слушателя кнопки
Show
Answer
Листинг 5.14. Назначение результата (CheatActivity.java)
public class CheatActivity extends Activity {
public static final String EXTRA_ANSWER_IS_TRUE =
"com.bignerdranch.android.geoquiz.answer_is_true";
public static final String EXTRA_ANSWER_SHOWN =
"com.bignerdranch.android.geoquiz.answer_shown";
private void setAnswerShownResult(boolean isAnswerShown) {
Intent data = new Intent();
data.putExtra(EXTRA_ANSWER_SHOWN, isAnswerShown);
setResult(RESULT_OK, data);
}
@Override protected void onCreate(Bundle savedInstanceState) {
// Ответ будет показан только в том случае,
// если пользователь нажмет кнопку
setAnswerShownResult(false);
mShowAnswer.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
if (mAnswerIsTrue) {
mAnswerTextView.setText(R.string.true_button);
} else {
mAnswerTextView.setText(R.string.false_button);
}
setAnswerShownResult(true);
}
});
}

Передача данных между активностями
121
Когда пользователь нажимает кнопку
Show
Answer
,
CheatActivity упаковывает код результата и интент в вызове setResult(int,
Intent)
Затем, когда пользователь нажимает кнопку
Back для возвращения к
QuizActivity
,
ActivityManager вызывает следующий метод родительской активности:
protected void onActivityResult(int requestCode, int resultCode, Intent data)
В параметрах передается исходный код запроса от
QuizActivity
, код результата и интент, переданный setResult(…)
Последовательность взаимодействий изображена на рис. 5.12.
ОС Android
Пользователь нажимает кнопку Cheat!, вызывается метод onClick(View)
Пользователь нажимает кнопку Show Answer, вызывается метод setResult(…)
Пользователь нажимает кнопку
Back
Рис. 5.12. Диаграмма последовательности для GeoQuiz
Остается последний шаг: переопределение onActivityResult(int,
int,
Intent)
в
QuizActivity для обработки результата.
Обработка результата
Добавьте в
QuizActivity.java новую переменную для хранения значения, возвращае- мого
CheatActivity
. Затем включите в переопределение onActivityResult(…)
код его получения.

122
Глава 5. Вторая активность
Листинг 5.15. Реализация onactivityResult(…) (QuizActivity.java)
public class QuizActivity extends Activity {
private int mCurrentIndex = 0;
private boolean mIsCheater;
...
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (data == null) {
return;
}
mIsCheater = data.getBooleanExtra(CheatActivity.EXTRA_ANSWER_SHOWN, false);
}
}
В этой реализации onActivityResult(…)
QuizActivity не проверяет ни код запроса, ни код результата. В других ситуациях в программу могут включаться условные конструкции, основанные на проверке этих значений.
Наконец, измените метод checkAnswer(boolean)
в
QuizActivity
. Он должен прове- рять, подсмотрел ли пользователь ответ, и реагировать соответствующим образом.
Листинг 5.16. Изменение уведомления в зависимости от значения mIsCheater (QuizActivity.java)
private void checkAnswer(boolean userPressedTrue) {
boolean answerIsTrue = mAnswerKey[mCurrentIndex].isTrueQuestion();
int messageResId = 0;
if (mIsCheater) {
messageResId = R.string.judgment_toast;
} else {
if (userPressedTrue == answerIsTrue) {
messageResId = R.string.correct_toast;
} else {
messageResId = R.string.incorrect_toast;
}
}
Toast.makeText(this, messageResId, Toast.LENGTH_SHORT)
.show();
}
@Override protected void onCreate(Bundle savedInstanceState) {
mNextButton = (Button)findViewById(R.id.next_button);
mNextButton.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
mCurrentIndex = (mCurrentIndex + 1) % mAnswerKey.length;

Ваши активности с точки зрения Android
123
mIsCheater = false;
updateQuestion();
}
});
}
Запустите приложение GeoQuiz. Попробуйте подсмотреть ответ и посмотрите, что произойдет.
Ваши активности с точки зрения Android
Давайте посмотрим, что происходит при переключении между активностями с точки зрения ОС. Прежде всего, когда вы щелкаете на приложении GeoQuiz в лаунчере,
ОС запускает не приложение, а активность в приложении. А если говорить точнее, запускается активность лаунчера приложения. Для GeoQuiz активностью лаунчера является
QuizActivity
Когда шаблон создавал приложение GeoQuiz, класс
QuizActivity был назначен активностью лаунчера по умолчанию. Статус активности лаунчера задается в ма- нифесте элементом intent-filter в объявлении
QuizActivity
(листинг 5.17).
Листинг 5.17. QuizActivity объявляется активностью лаунчера (AndroidManifest.xml)

... >
... >
android:label="@string/app_name" >





android:label="@string/app_name" />


Когда экземпляр
QuizActivity окажется на экране, пользователь может нажать кнопку
Cheat!
. При этом экземпляр
CheatActivity запускается поверх
QuizActivity
Эти активности образуют стек (рис. 5.13).
При нажатии кнопки
Back в
CheatActivity этот экземпляр выводится из стека, а
QuizActivity занимает свою позицию на вершине.

124
1   ...   8   9   10   11   12   13   14   15   ...   55

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

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

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