Освой Android играючи
/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000
Общее знакомство с компонентом описано в отдельной статье.
Адаптер PagerAdapter можно использовать в тех случаях, когда вам не нужны фрагменты.
Подготовим простую разметку для активности.
<?xml version="1.0" encoding="utf-8"?>
<androidx.viewpager.widget.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Подготовим отдельную разметку для ViewPager. Для демонстрации я выбрал три текстовых поля и контейнер для изображений
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:padding="10dp" >
<TextView
android:id="@+id/textViewRank"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/textViewName"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/textViewCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/imageViewAvatar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#000000"
android:padding="1dp" />
</LinearLayout>
Теперь напишем адаптер для ViewPager на основе PagerAdapter. Для адаптера требуются данные следующего вида: три строковых массива и один массив drawable-ресурсов.
package ru.alexanderklimov.viewpager;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.viewpager.widget.PagerAdapter;
public class ViewPagerAdapter extends PagerAdapter {
private Context mContext;
private String[] mRanks;
private String[] mCatNames;
private String[] mCounters;
private int[] mPictureIDs;
public ViewPagerAdapter(Context context, String[] ranks, String[] names,
String[] counters, int[] resids) {
this.mContext = context;
this.mRanks = ranks;
this.mCatNames = names;
this.mCounters = counters;
this.mPictureIDs = resids;
}
@Override
public int getCount() {
return mRanks.length;
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view == object;
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
TextView rankTextView;
TextView nameTextView;
TextView counterTextView;
ImageView avatarImageView;
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = inflater.inflate(R.layout.pager, container,
false);
rankTextView = itemView.findViewById(R.id.textViewRank);
nameTextView = itemView.findViewById(R.id.textViewName);
counterTextView = itemView.findViewById(R.id.textViewCount);
rankTextView.setText(mRanks[position]);
nameTextView.setText(mCatNames[position]);
counterTextView.setText(mCounters[position]);
avatarImageView = itemView.findViewById(R.id.imageViewAvatar);
avatarImageView.setImageResource(mPictureIDs[position]);
container.addView(itemView);
return itemView;
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
container.removeView((LinearLayout) object);
}
}
Осталось написать код для активности. Представьте себе, что где-то проводится чемпионат по ловле мышек. Всего в чемпионате приняло участие десять котов. Жюри подвело итоги, распределило места в соответствии с количеством пойманных мышей. И мы хотим просмотреть всех участников, листая экран. Естественно, вы можете придумать свой сценарий. Вам нужно подготовить десять изображений и три строковых массива для занятого места, имени кота и количества мышей.
package ru.alexanderklimov.viewpager;
// Если этот код работает, его написал Александр Климов,
// а если нет, то не знаю, кто его писал.
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_2);
String[] ranks = new String[]{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"};
String[] names = new String[]{"Васька", "Барсик", "Мурзик", "Рыжик", "Пушок",
"Снежок", "Борис", "Филя", "Сёма", "Кузя"};
String[] counts = new String[]{"880", "760", "758", "702", "690", "674", "651",
"649", "630", "625"};
int[] pictureIds = new int[]{R.drawable.cat1, R.drawable.cat2,
R.drawable.cat3, R.drawable.cat4, R.drawable.cat5,
R.drawable.cat1, R.drawable.cat2, R.drawable.cat3,
R.drawable.cat4, R.drawable.cat5};
ViewPager viewPager = findViewById(R.id.viewpager);
PagerAdapter adapter = new ViewPagerAdapter(MainActivity.this, ranks, names, counts,
pictureIds);
viewPager.setAdapter(adapter);
viewPager.setCurrentItem(5);
}
}
В демонстрационных целях при загрузке приложения мы выводим шестого участника, а далее можем листать влево или вправо.
На одном сайте я подглядел интересную идею создания бесконечной прокрутки картинок. Переделать существующий адаптер очень просто. Нужно добавить дополнительную переменную и установить новое значение для счётчика страниц.
private int mPos = 0;
@Override
public int getCount() {
return Integer.MAX_VALUE;
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
TextView rankTextView;
TextView nameTextView;
TextView counterTextView;
ImageView avatarImageView;
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = inflater.inflate(R.layout.pager, container,
false);
rankTextView = itemView.findViewById(R.id.textViewRank);
nameTextView = itemView.findViewById(R.id.textViewName);
counterTextView = itemView.findViewById(R.id.textViewCount);
rankTextView.setText(mRanks[mPos]);
nameTextView.setText(mCatNames[mPos]);
counterTextView.setText(mCounters[mPos]);
avatarImageView = itemView.findViewById(R.id.imageViewAvatar);
avatarImageView.setImageResource(mPictureIDs[mPos]);
container.addView(itemView);
if(mPos >= mRanks.length - 1){
mPos = 0;
}else {
mPos++;
}
return itemView;
}
В методе getCount() мы устанавливаем максимальное возможное значение, а счётчик mPos используется вместо параметра position и сбрасывается при определённом условии. Теперь, если листать страницы в одну сторону, то перелистывание будет бесконечным. Если начать листать в противоположную сторону, то бесконечное перелистывание сохранится, но поведение будет несколько непредсказуемым. Если вы запустите пример, то увидите, что я имею в виду. Это происходит потому, что мы не проверяем направление перелистывание страницы и счётчик продолжает увеличиваться. Вам надо подумать над этим вопросом и придумать свой совершенный код.