Вызов Activity
Приложение не всегда состоит из одного экрана. Например, мы создали очень полезную программу и пользователю хочется узнать, кто же ее автор. Он нажимает на кнопку «О программе» и попадает на новое окно, где находится полезная информация о версии программы, авторе, веб-адресе сайта и т.д. Воспринимайте Activity как форму. Если вы посмотрите на код в файле HelloWorld.java, то увидите, что наш класс HelloWorld тоже относится к Activity.
public class HelloWorld extends Activity
Как нетрудно догадаться, нам нужно создать новый класс, который может быть похож на HelloWorld.java и как-то переключиться на него при нажатии кнопки.
Для эксперимента мы возьмем программу из предыдущего урока и будем использовать для опытов шестую кнопку. А пока создадим новую форму для отображения полезной информации. Например, покажем пользователю, что делает кот, когда идет налево и направо. Согласитесь, это очень важная информация, дающая ключ к разгадке Вселенной.
Создадим новый XML-файл разметки about.xml в папке res/layout. На прошлом занятии нам уже приходилось создавать новый XML-файл, поэтому трудностей быть не должно. На этот раз мы откажемся от поднадоевшего контейнера LinearLayout и воспользуемся контейнером ScrollView:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dip">
<TextView
android:id="@+id/about_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/about_text" />
</ScrollView>
Кстати, нам не понадобится создавать копию этой разметки для альбомной ориентации, так как наш вариант будет хорошо смотреться в любой ориентации.
Мы определили, что информация будет извлекаться из ресурсов, а именно из строкового ресурса about_text. Открываем файл res/values/strings.xml и вводим следующий текст:
<string name="about_text">
У лукоморья дуб зелёный;\n
Златая цепь на дубе том:\n
И днём и ночью <b>кот учёный</b>\n
Всё ходит по цепи кругом;\n
Идёт <b>направо</b> - песнь заводит,\n
<b>Налево</b> - сказку говорит.</string>
Обратите внимание, что мы можем использовать простейшие HTML-теги форматирования текста типа <b>, <i>, <u>. Для нашего примера достаточно выделить жирным слова, которые относятся к коту и направлению движения. Для перевода текста на новую строку используйте \n. Заодно давайте добавим еще один строковый ресурс для заголовка нового окна
<string name="about_title">О программе</string>
С разметкой покончено. Далее необходимо создать класс для окна About.java. Создаем новый класс в Eclipse: File | New | Class и заполняем нужные поля.
Source folder: FirstAndroidApp/src
Package: ru.alexanderklimov.helloworld
Name: About
Сам класс About.java будет выглядеть следующим образом:
package ru.alexanderklimov.helloworld;
import android.app.Activity;
import android.os.Bundle;
public class About extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.about);
}
}
Главное в этом классе - наличие методов onCreate и setContentView.
Теперь начинается самое главное. Наша задача - перейти на новую форму при щелчке на шестой кнопке. Переходим обратно к файлу HelloWorld.java и импортируем пространство имен Intent.
import android.content.Intent;
Теперь можем написать обработчик события Click для кнопки:
public void button6_Click(View v)
{
switch (v.getId())
{
case R.id.button6:
Intent i = new Intent(this, About.class);
startActivity(i);
break;
}
}
Здесь я использовал свой любимый способ обработки нажатия кнопки, о котором рассказывалось в занятии Щелчок кнопки/Счетчик ворон.
Маленькое отступление
В некоторых случаях Eclipse ругается на параметр this. В этом случае используйте getApplicationContext():
startActivity(new Intend(getApplicationContext(), About.class));
Данный вариант считается даже более предпочтительным, судя по документации. Контект приложения служит для получения доступа к настройкам и ресурсам, используемым несколькими экземплярами активности.
Получить доступ к контексту приложения текущего процесса можно через метод getApplicationContext():
Context context = getApplicationContext();
А поскольку класс Activity происходит от класса Context, вы можете использовать оператор this вместо явного указания контекста приложения.
Однако, продолжим. Для запуска новой формы на экране, нам необходимо сначала создать экземпляр класса Intent и указать свой класс About. После этого вызывается метод startActivity, который и запускает новое окно. Но если вы сейчас попытаетесь проверить работу приложения в эмуляторе, то получите сообщение об ошибке. Что мы сделали неправильно? Мы пропустили один важный шаг. Необходимо зарегистрировать наш новый Activity в манифесте AndroidManifest.xml. Найдите этот файл в своем проекте и дважды щелкните на нем. Откроется окно редактирования файла. Переключитесь в режим редактора кода (вкладка AndroidManifest.xml), и добавьте новый тег <activity> после первого тега activity для HelloWorld.
<activity android:name=".About"
android:label="@string/about_title">
</activity>
Вот и пригодился нам строковый ресурс about_title. Запускаем приложение, щелкаем на шестой кнопке и получаем окно О программе. Таким образом мы научились создавать новое окно и вызывать его по щелчку кнопки. А в нашем распоряжении появилась мегаудобная программа - у вас всегда под рукой будет подсказка, что делает кот, когда идет налево.
Еще раз обращаю внимание, что второй создаваемый класс должен наследоваться от Activity или ему похожих (ListActivity и др.), иметь XML-файл разметки и быть прописан в манифесте.
Передача данных между активностями
Мы использовали простейший пример для вызова другого окна. Но, иногда требуется не только вызвать новое окно, но и передать в него данные. Например, имя пользователя. В этом случае нужно задействовать специальную область extraData, который имеется у класса Intent.
Область extraData - это список пар ключ/значение, который передается вместе с намерением. В качестве ключей используются строки, а для значений можно использовать любые примитивные типы данных, массивы примитивов, объекты класса Bundle и др.
Для передачи данных в другую активность используется метод putExtra:
intent.putExtra("Имя", i);
Принимающая активность должна вызвать метод getIntExtra():
int count = getIntent().getIntExtra("name", 0);
Напишем следующий пример. Создадим две активности как обычно. И на первой форме разместим два текстовых поля и кнопку.
У второй активности установим элемент TextView, в котором будем выводить какой-нибудь текст. Код для него будет следующим.
public class Privet extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.privet);
TextView txtInfo = (TextView)findViewById(R.id.textView1);
String user = "ЖЫвотное";
String gift = "дырку от бублика";
txtInfo.setText(user + " , вам передали " + gift);
}
}
Если сейчас запустить программу и вызвать второе окно, как это было описано в первой части статьи, то мы увидим надпись по умолчанию ЖЫвотное, вам передали дырку от бублика. Согласитесь, довольно обидно получать такие сообщения.
Исправляем ситуацию. Добавляем код у первой активности:
@Override
public void onClick(View v) {
Intent intent = new Intent(PassingDataDemoActivity.this, Privet.class);
intent.putExtra("username", edUserName.getText().toString()); // в ключ username пихаем текст из текстового поля
intent.putExtra("gift", edDescription.getText().toString()); // в ключ gift пихаем текст из текстового поля
startActivity(intent);
}
Итак, мы поместили в специальный контейнер у объекта Intend два ключа со значениями, которые берутся из текстового поля. Когда пользователь введет данные в текстовые поля, они попадут в этот контейнер и будет переданы второй активности.
Вторая активность должна быть готова к теплому приему сообщений следующим образом (выделено жирным).
TextView txtInfo = (TextView)findViewById(R.id.textView1);
String user = "ЖЫвотное";
String gift = "дырку от бублика";
user = getIntent().getExtras().getString("username");
gift = getIntent().getExtras().getString("gift");
txtInfo.setText(user + " , вам передали " + gift);
Теперь сообщение выглядит не столь обидным, а даже приятным для кое-кого.
У программы есть недостаток - не понятно, от кого мы получаем приветы. Любая хорошо воспитанная мартышка не возьмет подарка от анонима. Поэтому в качестве домашнего задания добавьте еще одно текстовое поле для ввода имени пользователя, который отправляет сообщение.

