Статьи

Android Full App, часть 5: запуск новых действий с намерениями

Это пятая часть серии «Полное руководство по Android» . Полное приложение предназначено, чтобы обеспечить легкий способ выполнять поиск фильмов / актеров через Интернет. В первой части серии ( «Основной интерфейс действий» ) мы создали проект Eclipse и настроили базовый интерфейс для основной деятельности приложения. Во второй части ( «Использование HTTP API» ) мы использовали клиентскую библиотеку Apache HTTP для использования внешнего HTTP API и интеграции возможностей поиска API в наше приложение. В третьей части ( «Анализ XML-ответа» ) мы увидели, как анализировать XML-ответ, используя встроенные в Android возможности синтаксического анализа XML. В четвертой части ( «Выполнение запроса API асинхронно из основного действия» ) мы связали вместе службы HTTP-ретривера и XML-парсера, чтобы выполнить запрос поиска API из основного действия нашего приложения. Запрос был выполнен асинхронно в фоновом потоке, чтобы избежать блокировки основного потока пользовательского интерфейса. В этой части мы увидим, как запустить новое действие и как перенести данные из одного действия в другое.

Google опубликовал « Руководства по разработке заданий и задач», в которых описываются основные принципы инфраструктуры приложений Android с высокоуровневой, ориентированной на пользователя точки зрения, полезной для разработчиков взаимодействий и приложений, а также для разработчиков приложений. Вы должны взглянуть на руководящие принципы, но сейчас мы должны просто упомянуть несколько вещей о деятельности здесь:

  • Действия являются основными строительными блоками приложений Android.
  • Когда пользователь перемещается по пользовательскому интерфейсу, он начинает действия один за другим.
  • Каждое действие имеет жизненный цикл, который не зависит от других действий в его приложении или задаче.
  • Android ведет линейную навигационную историю действий, которые посетил пользователь (стек действий).
  • Данные могут быть переданы между действиями с помощью класса Intent .

До сих пор в нашем уроке мы выполняли поиск фильмов внутри основной деятельности и просто уведомляли пользователей о результатах с помощью Toast s. Теперь мы собираемся сделать еще один шаг и использовать новое упражнение, в котором результаты будут представлены в виде списка. По этой причине новое действие будет фактически расширять класс Android ListActivity , который представляет собой особый вид деятельности, который отображает список элементов путем привязки к источнику данных, такому как массив или курсор.

Новое действие будет запущено из основного посредством Намерения . Мы будем использовать конструктор Intent, который включает в себя Context и целевой класс . Из справочной документации мы читаем, что этот конструктор «предоставляет удобный способ создания намерения, предназначенного для выполнения жестко запрограммированного имени класса, вместо того, чтобы полагаться на то, что система найдет подходящий для вас класс». Поскольку мы знаем, какой деятельностью мы хотим заниматься Намерением , это подходящее.

Для передачи данных между этими двумя действиями мы будем использовать один из перегруженных методов putExtra, которые предлагает класс Intent . Передаваемые данные должны быть Serializable, и, поскольку ArrayList по умолчанию, мы также должны пометить наши классы модели (Movie / Person / Image) с помощью интерфейса mark. Наконец, мы используем метод startActivity для запуска известного нового действия.

Итак, внутри класса «PerformMovieSearchTask» мы используем следующий код для запуска нового действия, которое будет обрабатывать представление результатов поиска:

1
2
3
4
5
6
...
Intent intent =
 new Intent(MovieSearchAppActivity.this, MoviesListActivity.class);
intent.putExtra("movies", result);
startActivity(intent);
...

Не забудьте пометить классы модели как сериализуемые:

1
2
3
4
5
6
7
...
public class Movie implements Serializable
...
public class Person implements Serializable
...
public class Image implements Serializable
...

Чтобы система нашла новое действие, мы должны объявить его в нашем файле «AndroidManifest.xml». Это очень легко сделать, добавив следующую строку внутри элемента «application»:

1
2
3
...
<activity android:name=".MoviesListActivity" />
...

Новый ListActivity будет извлекать данные из своего метода onCreate . Чтобы сделать это, мы сначала берем ссылку на намерение, которое запустило действие, используя метод getIntent, который возвращает исходное намерение. Из этого мы получаем расширенные данные с помощью метода getSerializableExtra , где мы используем имя элемента, который был ранее добавлен с помощью метода putExtra . Поскольку метод возвращает объект Serializable , мы выполняем необходимое приведение.

Чтобы представить результаты поиска в списке, нам нужно использовать ArrayAdapter , то есть ListAdapter, который управляет ListView, поддерживаемым массивом произвольных объектов. ArrayAdapter будет инициализирован списком фильмов, извлеченным из исходного действия. Затем мы используем метод setListAdapter, чтобы связать нашу ListActivity с ArrayAdapter .

Мы хотим обрабатывать события кликов по каждому элементу списка, а более конкретно — открывать браузер на странице IMDB фильма. Таким образом, мы переопределяем метод onListItemClick , который вызывается при выборе элемента в списке. Внутри этого метода мы извлекаем объект Movie, связанный с элементом списка, используя ArrayAdapter , находим ID IMDB, а затем создаем URL страницы IMDB, который состоит из следующего:

Базовый URL: http://m.imdb.com/title/

и соответствующий идентификатор фильма. Затем мы создаем новый Intent с его действием, установленным в ACTION_VIEW . Это действие действия, которое обычно отображает данные для пользователя. В случае URL-адреса браузер по умолчанию будет запущен и перенаправлен на целевую страницу. Новое действие, которое обрабатывает намерение, запускается обычным методом startActivity .

Давайте посмотрим код для нашего класса «MoviesListActivity»:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package com.javacodegeeks.android.apps.moviesearchapp;
 
import java.util.ArrayList;
 
import android.app.ListActivity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
 
import com.javacodegeeks.android.apps.moviesearchapp.model.Movie;
 
public class MoviesListActivity extends ListActivity {
     
    private static final String IMDB_BASE_URL = "http://m.imdb.com/title/";
     
    private ArrayList<Movie> moviesList;
    private ArrayAdapter<Movie> moviesAdapter;
     
    @SuppressWarnings("unchecked")
    @Override
    public void onCreate(Bundle savedInstanceState) {
         
        super.onCreate(savedInstanceState);
        setContentView(R.layout.movies_layout);
         
        moviesList = (ArrayList<Movie>) getIntent().getSerializableExtra("movies");
         
        moviesAdapter = new ArrayAdapter<Movie>(this, android.R.layout.simple_list_item_1, moviesList);
         
        setListAdapter(moviesAdapter);
         
    }
 
    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
         
        super.onListItemClick(l, v, position, id);
        Movie movie = moviesAdapter.getItem(position);
         
        String imdbId = movie.imdbId;
        if (imdbId==null || imdbId.length()==0) {
            longToast(getString(R.string.no_imdb_id_found));
            return;
        }
         
        String imdbUrl = IMDB_BASE_URL + movie.imdbId;
         
        Intent imdbIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(imdbUrl));               
        startActivity(imdbIntent);
         
    }
     
    public void longToast(CharSequence message) {
        Toast.makeText(this, message, Toast.LENGTH_LONG).show();
    }
     
}

Обратите внимание, что ArrayAdapter использует метод toString каждого из инкапсулированных объектов, поэтому мы должны переопределить метод и предоставить более осмысленное представление:

1
2
3
4
5
6
7
8
@Override
public String toString() {
 StringBuilder builder = new StringBuilder();
 builder.append("Movie [name=");
 builder.append(name);
 builder.append("]");
 return builder.toString();
}

Файл макета, который описывает представление контента для нашей деятельности, должен иметь объявление ListView с идентификатором «@ + id / android: list». Кроме того, мы предоставляем TextView с идентификатором «@ + id / android: empty», который будет отображаться в том случае, если в списке нет элементов. Эти представления включены в LinearLayout , который представляет собой макет, который размещает своих дочерних элементов в один столбец или одну строку. Файл XML находится в папке «res / layout», он называется «movies_layout.xml» и имеет следующее содержимое:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
<?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"
   >
    
 <ListView
     android:id="@+id/android:list"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     />
 <TextView
     android:id="@+id/android:empty"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     android:text="@string/no_movies_found"/>
     
</LinearLayout>

Теперь запустите конфигурацию Eclipse, предоставьте строку запроса, выполните поиск видео и дождитесь получения результатов.

После извлечения будет вызван класс «MoviesListActivity», и результаты будут отображены в виде списка (с использованием метода toString , как упомянуто выше).

Вы можете прокрутить вниз (это автоматически обрабатывается Android) и щелкнуть фильм, для которого вы хотите найти подробности. Это вызовет событие, которое откроет браузер устройства и укажет на страницу IMDB фильма:

Большой! Информация о фильме прямо на наш смартфон! Вы можете скачать здесь созданный проект Eclipse.

Статьи по Теме :