В этом уроке мы разберемся с виджетом ViewPager
в ходе написания простого приложения. Мы рассмотрим основные настройки адаптера PagerAdapter (нужен для работы ViewPager) и реализуем 3 экрана виджета.
Краткий обзор ViewPager
Виджет ViewPager
позволяет пользователю делать свайпы (проводить пальцем по экрану с одной стороны в другую) по страницам с какими-то данными. Сам ViewPager
использует PagerAdapter
, который создает компоненты View и заполняет их какими-то переданными данными. По механизму взаимодействия это сравнимо с адаптером ListAdapter и ListView.
Пример создания ViewPager в Android
Давайте перейдем к практике и установим в макете activity_main.xml компоновку виджета ViewPager из библиотеки поддержки:
1 2 3 4 5 6 7 8 9 10 11 12 |
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="ua.com.prologistic.viewpagerapp.MainActivity"> <android.support.v4.view.ViewPager android:id="@+id/vpager" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout> |
Если у вас в RelativeLayout есть лишние отступы, которые были автоматически сгенерированы Android Studio, то просто удалите их.
А теперь создадим макеты для экранов виджета ViewPager
. Вот первый макет view_screen_1.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/holo_green_light" android:orientation="vertical"> <TextView android:id="@+id/textView_green" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:text="@string/txt_screen_1" android:textSize="25sp" /> </RelativeLayout> |
Остальные два view_screen_2.xml и view_screen_3.xml создайте по примеру первого с такими ресурсами:
1 2 3 4 5 6 7 |
<resources> <string name="app_name">ViewPagerApp</string> <string name="txt_screen_3">3-й экран</string> <string name="txt_screen_2">2-й экран</string> <string name="txt_screen_1">1-й экран</string> </resources> |
Отлично, теперь можно приступать к созданию класса-модели, который будет хранить ссылки на ресурсы в удобно для нас виде:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
package ua.com.prologistic.viewpagerapp; public enum ResourcesModel { // создаем 3 перечисления с тайтлом и макетом // для удобной работы в адаптере FIRST_SCREEN(R.string.txt_screen_1, R.layout.view_screen_1), SECOND_SCREEN(R.string.txt_screen_2, R.layout.view_screen_2), THIRD_SCREEN(R.string.txt_screen_3, R.layout.view_screen_3); private int mTitleResourceId; private int mLayoutResourceId; ResourcesModel(int titleResId, int layoutResId) { mTitleResourceId = titleResId; mLayoutResourceId = layoutResId; } public int getTitleResourceId() { return mTitleResourceId; } public int getLayoutResourceId() { return mLayoutResourceId; } } |
Внимание! Если вы не знакомы с типом данных Enum, то обязательно почитайте о нем здесь.
Теперь переходим к самому интересному — адаптеру для нашего ViewPager
:
1 2 3 4 5 6 7 8 9 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 |
package ua.com.prologistic.viewpagerapp; import android.content.Context; import android.support.v4.view.PagerAdapter; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class SimplePagerAdapter extends PagerAdapter { private Context mContext; public SimplePagerAdapter(Context context) { mContext = context; } @Override public Object instantiateItem(ViewGroup viewGroup, int position) { // получаем ресурсы (название и макет) соответствующий позиции в адаптере ResourcesModel resources = ResourcesModel.values()[position]; LayoutInflater inflater = LayoutInflater.from(mContext); // инициализируем экран ViewPager'а в соответствии с позицией ViewGroup layout = (ViewGroup) inflater.inflate( resources.getLayoutResourceId(), viewGroup, false); viewGroup.addView(layout); return layout; } @Override public void destroyItem(ViewGroup viewGroup, int position, Object view) { viewGroup.removeView((View) view); } @Override public int getCount() { // кличество элементов в адаптере соответствует // количеству значений в enum классе return ResourcesModel.values().length; } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public CharSequence getPageTitle(int position) { // получаем название соответствующее позиции в адаптере ResourcesModel customPagerEnum = ResourcesModel.values()[position]; return mContext.getString(customPagerEnum.getTitleResourceId()); } } |
Давайте вкратце рассмотрим основные методы, которые мы использовали при работе создании SimplePagerAdapter для лучшего понимания того, как он работает:
- Конструктор
SimplePagerAdapter(Context context)
принимает в качестве параметра контекст для инициализации переменной класса, которая используется для доступа к данным и создании компонентов View по этим данным. - Метод
instantiateItem(ViewGroup viewGroup, int position)
использует перечисление, которое соответствует конкретной позиции. Получает с него данные и возвращает сформированный компонент View. В дальнейшем этот объект используется методомisViewFromObject
. - Метод
destroyItem()
удаляет конкретный View из ViewGroup. - Метод
getCount()
просто возвращает количество View, которые использоваться в ViewPager. - Метод
isViewFromObject()
проверяет, соответствует ли конкретный объект данной позиции. Как описано чуть выше, второй параметр имеет тип Object и получается из методаinstantiateItem()
. - Метод
getPageTitle()
возвращает текст для заголовка каждого экрана. В нашей реализации мы не передавали его ActionBar.
Мы создали все макеты и настроили правильное отображение в адаптере, теперь давайте инициализируем наш ViewPager
готовым адаптером SimplePagerAdapter в методе onCreate()
класса MainActivity
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
package ua.com.prologistic.viewpagerapp; import android.os.Bundle; import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ViewPager viewPager = (ViewPager) findViewById(R.id.vpager); if (viewPager != null) { viewPager.setAdapter(new SimplePagerAdapter(this)); } } } |
Теперь осталось запустить наш простенький пример создания ViewPager в Android:
Как видите, у нас 3 экрана, которые можно листать простым свайпом.
Скачать проект приложения ViewPager в Android можно здесь.
Подписывайтесь на новые статьи по Java и Android и следите за обновлениями!
Отличный урок! Большое спасибо. Уже неделю ищу нормальный урок на эту тему, наконец нашёл, где все работает.
Пару вещей, которые я бы поправил:
1. «Отлично, теперь можно приступать к созданию класса-модели, который будет хранить ссылки на ресурсы в удобно для нас виде:» -Тут в слове «удобном» не хватает буквы «М».
2. «Остальные два view_screen_2.xml и view_screen_3.xml создайте по примеру первого с такими ресурсами:» -Не каждому начинающему понятно что такое ресурсы, стоило бы объяснить что это файл strings.xml и где он находится.
А можно ли обращаться к добавленным таким способом элементам (например, изменить текст)? И, если можно, то как?