フォトやGalleryのアプリなどは写真をスワイプで次々と遷移をさせていますが、これはViewPager2をRecyclerView.Adapterで利用すると可能です
2021.2.1
ViewPager2
ViewPager2でGalleryのように作るうえで、写真の数は比較的多くまた削除されることもあります。
ViewPager2では、様々なアプローチがありますが、
- 遷移する画面を個別に作成
- 毎回画面を自動で作成
- アダプターはFragmentStateAdapter
- アダプターはRecyclerView.Adapter
ここでは、2と4を想定して以下のように写真を3枚適当に用意してスライドさせてみます
RecyclerView.Adapterの例
作成するファイルは以下の4つです
- screen_slide_page.xml
- activity_maine.xml
- MainActivity.java
- TestAdapter.java
- RecyclerView.Adapterを継承したクラス
ビューを作成する
TextViewとImageViewを含む
スライドするコンテンツ用に使用するレイアウト ファイルを作成
screen_slide_page.xml
1 2 3 4 5 6 7 8 9 10 11 12 |
<?xml version="1.0" encoding="utf-8"?> <LinearLayout ... <TextView android:id="@+id/text_view" ... /> <ImageView android:id="@+id/image_view" ... /> </LinearLayout> |
ViewPager2 を追加する
Activityのレイアウトにviewpager2の
<androidx.viewpager2.widget.ViewPager2
… />
を設定する
activity_main.xml
1 2 3 4 5 6 7 8 9 10 |
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout ... <androidx.viewpager2.widget.ViewPager2 android:id="@+id/pager" android:layout_width="0dp" android:layout_height="0dp" ... /> </androidx.constraintlayout.widget.ConstraintLayout> |
3ページ用の写真を適当に用意してdrawableに入れておきリストにします
また、その写真の名前もリストにします
MainActivity.java
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 |
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // drawableに入れた写真をリストに追加 ArrayList<Integer> fruit = new ArrayList<>(); fruit.add(R.drawable.cherry); fruit.add(R.drawable.melon); fruit.add(R.drawable.watermelon); // 写真の名前をリストに追加 ArrayList<String> name = new ArrayList<>(); name.add("cherry"); name.add("melon"); name.add("watermelon"); // ViewPager2 を使用して、レイアウト用のコンテンツビューを設定 ViewPager2 pager = findViewById(R.id.pager); // ViewPager2 オブジェクトをAdapterに接続 // 写真と名前のリストを渡す pager.setAdapter(new TestAdapter(fruit, name)); } } |
RecyclerView.Adapterを継承したクラスの作成
写真と名前をArrayListに入れたので、それらをコンストラクタで受け取ります
RecyclerViewは定義された表示方法で動的に作成し、これらをリサイクルします
アイテムが画面外にスクロールされても、RecyclerViewはビューを破棄せず、画面上にスクロールされた新しいアイテムのビューを再利用します
これによりパフォーマンスの大幅な改善、アプリの応答性の向上、消費電力の削減になります
TestAdapter.java
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 |
public class TestAdapter extends RecyclerView.Adapter<TestAdapter.MyViewHolder> { ArrayList<Integer> img; ArrayList<String> txt; public TestAdapter(ArrayList<Integer> fruit, ArrayList<String> name) { this.img = fruit; this.txt = name; } static class MyViewHolder extends RecyclerView.ViewHolder { ImageView imageView; TextView textView; public MyViewHolder(View itemView) { super(itemView); imageView = itemView.findViewById(R.id.image_view); textView = itemView.findViewById(R.id.text_view); } } @NonNull @Override public MyViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { View view = LayoutInflater.from(viewGroup.getContext()) .inflate(R.layout.screen_slide_page, viewGroup, false); return new MyViewHolder(view); } @Override public void onBindViewHolder(@NonNull MyViewHolder holder, int position) { holder.textView.setText(txt.get(position)); holder.imageView.setImageResource(img.get(position)); } // getItemCount() メソッドを実装し、アダプターが作成するページの数を返す @Override public int getItemCount() { return txt.size(); } } |
サンプルコード
MainActivity.java
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 |
//package your.package.name; import androidx.appcompat.app.AppCompatActivity; import androidx.viewpager2.widget.ViewPager2; import android.os.Bundle; import java.util.ArrayList; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ArrayList<Integer> fruit = new ArrayList<>(); fruit.add(R.drawable.cherry); fruit.add(R.drawable.melon); fruit.add(R.drawable.watermelon); ArrayList<String> name = new ArrayList<>(); name.add("cherry"); name.add("melon"); name.add("watermelon"); ViewPager2 pager = findViewById(R.id.pager); pager.setAdapter(new TestAdapter(fruit, name)); } } |
TestAdapter.java
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 |
//package your.package.name; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; public class TestAdapter extends RecyclerView.Adapter<TestAdapter.MyViewHolder> { ArrayList<Integer> img; ArrayList<String> txt; public TestAdapter(ArrayList<Integer> fruit, ArrayList<String> name) { this.img = fruit; this.txt = name; } static class MyViewHolder extends RecyclerView.ViewHolder { ImageView imageView; TextView textView; public MyViewHolder(View itemView) { super(itemView); imageView = itemView.findViewById(R.id.image_view); textView = itemView.findViewById(R.id.text_view); } } @NonNull @Override public MyViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { // Create a new view, which defines the UI of the list item View view = LayoutInflater.from(viewGroup.getContext()) .inflate(R.layout.screen_slide_page, viewGroup, false); return new MyViewHolder(view); } @Override public void onBindViewHolder(@NonNull MyViewHolder holder, int position) { holder.textView.setText(txt.get(position)); holder.imageView.setImageResource(img.get(position)); } @Override public int getItemCount() { return txt.size(); } } |
activity_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <androidx.viewpager2.widget.ViewPager2 android:id="@+id/pager" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> |
screen_slide_page.xml
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 |
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="#000" tools:context=".MainActivity"> <TextView android:id="@+id/text_view" android:textColor="#fff" android:layout_width="match_parent" android:layout_height="wrap_content" /> <ImageView android:id="@+id/image_view" android:padding="16dp" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitCenter" android:contentDescription="@string/description"/> </LinearLayout> |
strings.xml
1 2 3 4 |
<resources> <string name="app_name">YourAppName</string> <string name="description">folwer</string> </resources> |
RecyclerViewでGrid表示にすることができますが
GridLayoutManager(this, 2, RecyclerView.VERTICAL, false));
このspanCountとorientationの引数を変える事で似たように作成することができます
References:
ViewPager2 を使用してフラグメント間をスライドする
ViewPager2
ViewPager から ViewPager2 に移行する