ViewPager с представлениями
ViewPager — это диспетчер макетов, который позволяет реализовать навигацию gestural. Навигация gestural позволяет пользователю проводите пальцем влево и вправо на страницы данных. В этом руководстве объясняется, как реализовать экранируемый пользовательский интерфейс с viewPager и PagerTabStrip, используя представления в качестве страниц данных (последующее руководство описывает использование фрагментов для страниц).
Обзор
Это пошаговое руководство, которое предоставляет пошаговую демонстрацию использования ViewPager
для реализации коллекции образов лиственных и вечнозеленых деревьев. В этом приложении пользователь проводит пальцем влево и вправо через "каталог деревьев" для просмотра изображений дерева. В верхней части каждой страницы каталога имя дерева отображается в спискеPagerTabStrip
, а изображение дерева отображается в виде ImageView
. Адаптер используется для интерфейса ViewPager
базовой модели данных. Это приложение реализует адаптер, производный от PagerAdapter
.
Хотя ViewPager
приложения на основе часто реализуются с помощью Fragment
S, существуют некоторые относительно простые варианты использования, где дополнительная сложность Fragment
s не требуется. Например, базовое приложение коллекции образов Fragment
, иллюстрированное в этом пошаговом руководстве, не требует использования s. Так как содержимое является статическим, и пользователь проводит пальцем вправо и вперед между различными изображениями, реализация может быть проще с помощью стандартных представлений и макетов Android.
Запуск проекта приложения
Создайте новый проект Android с именем TreePager (дополнительные сведения о создании проектов Android см. в разделе Hello, Android ). Затем запустите диспетчер пакетов NuGet. (Дополнительные сведения об установке пакетов NuGet см. в разделе .Пошаговое руководство. Включение NuGet в проект). Найдите и установите библиотеку поддержки Android версии 4:
Это также установит все дополнительные пакеты, повторно запрашиваемые библиотекой поддержки Android версии 4.
Добавление примера источника данных
В этом примере источник данных каталога дерева (представленный TreeCatalog
классом) предоставляет содержимое ViewPager
элемента.
TreeCatalog
содержит готовую коллекцию изображений деревьев и заголовков деревьев, которые адаптер будет использовать для создания View
s. Конструктору TreeCatalog
не требуются аргументы:
TreeCatalog treeCatalog = new TreeCatalog();
Коллекция изображений организована TreeCatalog
таким образом, чтобы доступ к каждому изображению можно получить индексатором. Например, следующая строка кода извлекает идентификатор ресурса образа для третьего образа в коллекции:
int imageId = treeCatalog[2].imageId;
Поскольку сведения о TreeCatalog
реализации не относятся к пониманию ViewPager
, TreeCatalog
код не указан здесь.
Исходный код TreeCatalog
доступен по адресу TreeCatalog.cs.
Скачайте этот исходный файл (или скопируйте и вставьте код в новый файл TreeCatalog.cs ) и добавьте его в проект. Кроме того, скачайте и распакуйте файлы изображений в папку Resources/drawable и включите их в проект.
Создание макета ViewPager
Откройте файл Resources/layout/Main.axml и замените его содержимое следующим XML-кодом:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</android.support.v4.view.ViewPager>
Этот XML-код определяет ViewPager
, который занимает весь экран. Обратите внимание, что необходимо использовать полное имя android.support.v4.view.ViewPager , так как ViewPager
упаковано в библиотеку поддержки. ViewPager
доступна только из библиотеки поддержки Android версии 4. Она недоступна в пакете SDK для Android.
Настройка ViewPager
Измените MainActivity.cs и добавьте следующую using
инструкцию:
using Android.Support.V4.View;
Замените метод OnCreate
следующим кодом:
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
ViewPager viewPager = FindViewById<ViewPager>(Resource.Id.viewpager);
TreeCatalog treeCatalog = new TreeCatalog();
}
Этот код выполняет следующие действия:
Задает представление из ресурса макета Main.axml .
Извлекает ссылку на
ViewPager
макет.Создает экземпляр нового
TreeCatalog
источника данных.
При сборке и запуске этого кода вы увидите дисплей, похожий на следующий снимок экрана:
На этом этапе он пуст, ViewPager
так как он не имеет адаптера для доступа к содержимому в TreeCatalog. В следующем разделе создается PagerAdapter для подключения ViewPager
к TreeCatalog.
Создание адаптера
ViewPager
использует объект контроллера адаптера, который находится между ViewPager
источником данных и источником данных (см. иллюстрацию в адаптере). Для доступа к этим данным требуется предоставить пользовательский адаптер, ViewPager
производный от PagerAdapter
. Этот адаптер заполняет каждую ViewPager
страницу содержимым из источника данных. Так как этот источник данных зависит от приложения, настраиваемый адаптер — это код, который понимает, как получить доступ к данным. По мере того как пользователь проводит пальцем по страницам ViewPager
, адаптер извлекает сведения из источника данных и загружает его на страницы для ViewPager
отображения.
При реализации PagerAdapter
необходимо переопределить следующее:
InstantiateItem — создает страницу (
View
) для заданной позиции и добавляет ее вViewPager
коллекцию представлений.DestroyItem — удаляет страницу из заданной позиции.
Count — свойство только для чтения, которое возвращает количество доступных представлений (страниц).
IsViewFromObject — определяет, связана ли страница с определенным ключевым объектом. (Этот объект создается методом
InstantiateItem
.) В этом примере ключевойTreeCatalog
объект является объектом данных.
Добавьте новый файл с именем TreePagerAdapter.cs и замените его содержимое следующим кодом:
using System;
using Android.App;
using Android.Runtime;
using Android.Content;
using Android.Views;
using Android.Widget;
using Android.Support.V4.View;
using Java.Lang;
namespace TreePager
{
class TreePagerAdapter : PagerAdapter
{
public override int Count
{
get { throw new NotImplementedException(); }
}
public override bool IsViewFromObject(View view, Java.Lang.Object obj)
{
throw new NotImplementedException();
}
public override Java.Lang.Object InstantiateItem (View container, int position)
{
throw new NotImplementedException();
}
public override void DestroyItem(View container, int position, Java.Lang.Object view)
{
throw new NotImplementedException();
}
}
}
Этот код заглушает основную PagerAdapter
реализацию. В следующих разделах каждый из этих методов заменяется рабочим кодом.
Реализация конструктора
Когда приложение создает экземпляр TreePagerAdapter
, оно предоставляет контекст (the MainActivity
) и создает экземпляр TreeCatalog
. Добавьте следующие переменные-члены и конструктор в начало TreePagerAdapter
класса в TreePagerAdapter.cs:
Context context;
TreeCatalog treeCatalog;
public TreePagerAdapter (Context context, TreeCatalog treeCatalog)
{
this.context = context;
this.treeCatalog = treeCatalog;
}
Цель этого конструктора заключается в хранении контекста и TreeCatalog
экземпляра TreePagerAdapter
, который будет использоваться.
Реализация счетчика
Реализация Count
относительно проста: она возвращает количество деревьев в каталоге деревьев. Замените Count
следующим кодом:
public override int Count
{
get { return treeCatalog.NumTrees; }
}
Свойство NumTrees
TreeCatalog
возвращает количество деревьев (количество страниц) в наборе данных.
Реализация InstantiateItem
Метод InstantiateItem
создает страницу для заданной позиции. Он также должен добавить только что созданное представление в коллекцию представлений ViewPager
. Чтобы сделать это возможным, он ViewPager
передает себя в качестве параметра контейнера.
Замените метод InstantiateItem
следующим кодом:
public override Java.Lang.Object InstantiateItem (View container, int position)
{
var imageView = new ImageView (context);
imageView.SetImageResource (treeCatalog[position].imageId);
var viewPager = container.JavaCast<ViewPager>();
viewPager.AddView (imageView);
return imageView;
}
Этот код выполняет следующие действия:
Создает экземпляр нового
ImageView
для отображения изображения дерева в указанной позиции. ПриложениеMainActivity
— это контекст, который будет передан конструкторуImageView
.ImageView
Задает ресурс идентификаторуTreeCatalog
ресурса изображения в указанной позиции.Приведение переданного контейнера
View
к ссылкеViewPager
. Обратите внимание, что для правильного выполнения этого приведения необходимо использоватьJavaCast<ViewPager>()
(это необходимо, чтобы Android выполнял преобразование типа, проверяемого средой выполнения).Добавляет экземпляр
ImageView
ViewPager
в вызывающий объект и возвращает вызывающийImageView
объект.
При отображении ViewPager
изображения position
отображается это ImageView
. Изначально вызывается дважды, InstantiateItem
чтобы заполнить первые две страницы представлениями. По мере прокрутки пользователя он снова вызывается для поддержания представлений непосредственно за пределами и впереди отображаемого в данный момент элемента.
Реализация DestroyItem
Метод DestroyItem
удаляет страницу из заданной позиции. В приложениях, где представление с любой заданной позицией может измениться, ViewPager
должен иметь некоторый способ удаления устаревшего представления на этой позиции, прежде чем заменить его новым представлением. TreeCatalog
В примере представление на каждой позиции не изменяется, поэтому представление, удаленное DestroyItem
путем, просто будет повторно добавлено при InstantiateItem
вызове этой позиции.
(Для повышения эффективности можно реализовать пул для перезапуска View
, который будет повторно отображаться в той же позиции.)
Замените метод DestroyItem
следующим кодом:
public override void DestroyItem(View container, int position, Java.Lang.Object view)
{
var viewPager = container.JavaCast<ViewPager>();
viewPager.RemoveView(view as View);
}
Этот код выполняет следующие действия:
Приведение переданного контейнера
View
в ссылкуViewPager
.Приведение переданного объекта Java (
view
) в C#View
(view as View
);Удаляет представление из
ViewPager
.
Реализация IsViewFromObject
По мере того как пользователь перемещается влево и вправо через страницы содержимого, ViewPager
вызывается IsViewFromObject
проверка того, что дочерний элемент View
в заданной позиции связан с объектом адаптера для той же позиции (следовательно, объект адаптера называется ключом объекта). Для относительно простых приложений связь является одной из удостоверений — ключ объекта адаптера в этом экземпляре — это представление, которое ранее было возвращено через ViewPager
InstantiateItem
. Однако для других приложений ключ объекта может быть другим экземпляром класса, связанным с (но не таким же, как) дочерним представлением, ViewPager
отображающимся в этой позиции. Только адаптер знает, связаны ли переданные представления и ключ объекта.
IsViewFromObject
необходимо реализовать PagerAdapter
для правильной работы. Если IsViewFromObject
возвращается false
для заданной позиции, ViewPager
представление не будет отображаться в этой позиции. TreePager
В приложении ключ объекта, возвращаемый InstantiateItem
страницей View
дерева, поэтому код должен проверять только удостоверение (т. е. ключ объекта и представление одно и то же). Замените IsViewFromObject
следующим кодом:
public override bool IsViewFromObject(View view, Java.Lang.Object obj)
{
return view == obj;
}
Добавление адаптера в ViewPager
Теперь, когда TreePagerAdapter
реализация реализована, пришло время добавить его в ViewPager
. В MainActivity.cs добавьте следующую строку кода в конец OnCreate
метода:
viewPager.Adapter = new TreePagerAdapter(this, treeCatalog);
Этот код создает TreePagerAdapter
экземпляр , передаваемый в MainActivity
качестве контекста (this
). Экземпляр TreeCatalog
передается во второй аргумент конструктора. Свойство ViewPager
's Adapter
задано для экземпляра TreePagerAdapter
объекта; он подключается к объекту TreePagerAdapter
ViewPager
.
Базовая реализация завершена — сборка и запуск приложения. На экране появится первое изображение каталога деревьев, как показано слева на следующем снимке экрана. Проводите пальцем влево, чтобы увидеть больше представлений дерева, а затем проводите пальцем вправо, чтобы вернуться к каталогу деревьев:
Добавление индикатора pager
Эта минимальная ViewPager
реализация отображает изображения каталога деревьев, но не указывает, где пользователь находится в каталоге. Следующий шаг — добавить PagerTabStrip
. Пользователь PagerTabStrip
сообщает пользователю о том, какая страница отображается и предоставляет контекст навигации, отображая намек на предыдущие и следующие страницы. PagerTabStrip
Предназначено для использования в качестве индикатора текущей страницы объекта ViewPager
; она прокручивает и обновляется, когда пользователь проводит пальцем по каждой странице.
Откройте resources/layout/Main.axml и добавьте в PagerTabStrip
макет:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v4.view.PagerTabStrip
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:paddingBottom="10dp"
android:paddingTop="10dp"
android:textColor="#fff" />
</android.support.v4.view.ViewPager>
ViewPager
и PagerTabStrip
предназначены для совместной работы. При объявлении PagerTabStrip
внутри макета ViewPager
ViewPager
он будет автоматически находить PagerTabStrip
и подключать его к адаптеру. При сборке и запуске приложения должно отображаться пустое PagerTabStrip
в верхней части каждого экрана:
Отображение заголовка
Чтобы добавить заголовок на каждую вкладку страницы, реализуйте GetPageTitleFormatted
метод в производном PagerAdapter
классе. ViewPager
вызовы GetPageTitleFormatted
(если реализованы), чтобы получить строку заголовка, описывающую страницу в указанной позиции. Добавьте следующий метод в TreePagerAdapter
класс в TreePagerAdapter.cs:
public override Java.Lang.ICharSequence GetPageTitleFormatted(int position)
{
return new Java.Lang.String(treeCatalog[position].caption);
}
Этот код извлекает строку заголовка дерева из указанной страницы (позиции) в каталоге деревьев, преобразует его в Java String
и возвращает его в ViewPager
. При запуске приложения с этим новым методом на каждой странице отображается подпись дерева в файле PagerTabStrip
. Имя дерева должно отображаться в верхней части экрана без подчеркивания:
Чтобы просмотреть каждый заголовок дерева в каталоге, проводите пальцем вправо и вперед.
Вариант PagerTitleStrip
PagerTitleStrip
очень похоже на то, что PagerTabStrip
PagerTabStrip
добавляет подчеркивание для выбранной в данный момент вкладки. Вы можете заменить PagerTabStrip
его PagerTitleStrip
в приведенном выше макете и снова запустить приложение, чтобы увидеть, как он выглядит следующим PagerTitleStrip
образом:
Обратите внимание, что подчеркивание удаляется при преобразовании PagerTitleStrip
в .
Итоги
В этом пошаговом руководстве представлен пошаговый пример создания базового ViewPager
приложения без использования Fragment
S. В нем представлен пример источника данных, содержащего изображения и строки заголовка, ViewPager
макет для отображения изображений и PagerAdapter
подкласс, который подключается ViewPager
к источнику данных. Чтобы помочь пользователю перемещаться по набору данных, были включены инструкции, которые объясняют, как добавить PagerTabStrip
или PagerTitleStrip
отобразить подпись изображения в верхней части каждой страницы.