ViewPager2はスワイプで次々とページの画面遷移をさせるために利用します
作成方法は様々ありますが、シンプルにFragmentStateAdapterを使ってFragmentのページ遷移をさせてみます
2021.2.1
ViewPager2
ViewPager2ではスライドショーを作ることができ、ページがパッパッと変わるのではなくアニメーションを自動でやってくれます
ViewPager2では、様々なアプローチがありますが、
- 遷移する画面を個別に作成
- 毎回画面を自動で作成
- アダプターはFragmentStateAdapter
- アダプターはRecyclerView.Adapter
ここでは、1と3を想定して作成してみます
1. ViewPager2の例
1.1 画面のレイアウト
1.2 Fragment作成
1.3 Adapterの作成
1.4 ViewPager2の追加
2. サンプルコード
3. サンプルコード2
ViewPager2の例
分かりやすく画面の遷移させるためのFragmentを
3つ作成してスライドさせてみます
画面のレイアウト
スライドする画面のレイアウトを作成します
とりあえずページ表示する文字と背景色を変えられるようにします
fragment_page1.xml
1 2 3 4 5 6 7 8 9 10 11 |
<?xml version="1.0" encoding="utf-8"?> </androidx.constraintlayout.widget.ConstraintLayout ... android:background="#dfe" ... <TextView android:id="@+id/text_view1" android:text="@string/page01" ... /> </androidx.constraintlayout.widget.ConstraintLayout> |
Fragment作成
先に作成したレイアウトfragment_page1.xmlをonCreateView()に返すFragmentを作成します
冗長ですが分かりやすくするために、FragmentはonCreateView()とそれに属するレイアウトだけのシンプルなFragmentとそのレイアウトをそれぞれ3つ作成したいと思います
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import androidx.fragment.app.Fragment; public class Fragment01 extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Log.d("debug", "onCreateView"); return inflater.inflate(R.layout.fragment_page1, container, false); } } |
Adapterの作成
FragmentStateAdapter のコンストラクタ パラメータとして以下の選択肢があります
- ViewPager2 オブジェクトが存在する FragmentActivity オブジェクトまたは Fragment オブジェクト、この方法が推奨されます
- FragmentManager オブジェクトと Lifecycle オブジェクト
ここではFragmentActivityを使います
FragmentStateAdapterを継承したTestAdapterの作成
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 |
public class TestAdapter extends FragmentStateAdapter { private static final int Pages = 3; public TestAdapter(@NonNull FragmentActivity fragment) { super(fragment); } // positionに応じてFragmentを新しいページとして供給 @NonNull @Override public Fragment createFragment(int position) { if(position == 0){ return new Fragment01(); } else if(position == 1){ return new Fragment02(); } else if(position == 2){ return new Fragment03(); } else { return new Fragment01(); } } // ページャーアダプターを利用するためgetItemCount() メソッドを実装 @Override public int getItemCount() { return Pages; } } |
ViewPager2の追加
ViewPager2にはデフォルトで画面スライド アニメーションが表示されます
ViewPager2オブジェクトを含むレイアウトを作成
<androidx.viewpager2.widget.ViewPager2
activity_main.xml
1 2 3 4 5 6 7 8 9 |
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout ... <androidx.viewpager2.widget.ViewPager2 android:id="@+id/view_pager2" android:layout_width="0dp" android:layout_height="0dp" ... /> </androidx.constraintlayout.widget.ConstraintLayout> |
Activityに、ViewPager2を使ったレイアウト用のコンテンツ ビューの設定
表示する新しいページを供給するためにアダプター クラスを使いますが、2種類あります
- FragmentStateAdapter
- RecyclerView.Adapter
ここではFragmentStateAdapterを使っていきます
Activityを設定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // ViewPager2 を使用して、レイアウト用のコンテンツ ビューを設定 ViewPager2 viewPager2 = findViewById(R.id.view_pager2); TestAdapter adapter = new TestAdapter(this); // ViewPager2 水平方向にスライド viewPager2.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL); // 垂直方向にスライド //viewPager2.setOrientation(ViewPager2.ORIENTATION_VERTICAL); // FragmentStateAdapter を ViewPager2 オブジェクトに接続 viewPager2.setAdapter(adapter); } |
サンプルコード
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 |
//package your.package.name; import androidx.appcompat.app.AppCompatActivity; import androidx.viewpager2.widget.ViewPager2; import android.os.Bundle; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ViewPager2 viewPager2 = findViewById(R.id.view_pager2); TestAdapter adapter = new TestAdapter(this); // set Orientation in your ViewPager2 viewPager2.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL); //viewPager2.setOrientation(ViewPager2.ORIENTATION_VERTICAL); viewPager2.setAdapter(adapter); } } |
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 |
//package your.package.name; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.viewpager2.adapter.FragmentStateAdapter; public class TestAdapter extends FragmentStateAdapter { private static final int Pages = 3; public TestAdapter(@NonNull FragmentActivity fragment) { super(fragment); } @NonNull @Override public Fragment createFragment(int position) { if(position == 0){ return new Fragment01(); } else if(position == 1){ return new Fragment02(); } else if(position == 2){ return new Fragment03(); } else { return new Fragment01(); } } @Override public int getItemCount() { return Pages; } } |
ライブラリーの追加、これはTabLayoutなどを使う場合に必要です(このサンプルでは無くても動きます)
build.gradle
1 2 3 4 |
dependencies { implementation 'androidx.viewpager2:viewpager2:1.1.0-beta01' ... } |
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/view_pager2" 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> |
Fragment01,java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
//package your.package.name; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import androidx.fragment.app.Fragment; public class Fragment01 extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Log.d("debug", "onCreateView"); return inflater.inflate(R.layout.fragment_page1, container, false); } } |
Fragment02,java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
//package your.package.name; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import androidx.fragment.app.Fragment; public class Fragment02extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Log.d("debug", "onCreateView"); return inflater.inflate(R.layout.fragment_page2, container, false); } } |
Fragment03,java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
//package your.package.name; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import androidx.fragment.app.Fragment; public class Fragment03extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Log.d("debug", "onCreateView"); return inflater.inflate(R.layout.fragment_page3, container, false); } } |
fragment_page1.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?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" android:background="#dfe" tools:context=".MainActivity"> <TextView android:id="@+id/text_view1" android:text="@string/page01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="30sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> |
fragment_page2.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?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" android:background="#fde" tools:context=".MainActivity"> <TextView android:id="@+id/text_view2" android:text="@string/page02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="30sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> |
fragment_page3.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?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" android:background="#def" tools:context=".MainActivity"> <TextView android:id="@+id/text_view3" android:text="@string/page03" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="30sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> |
strings.xml
1 2 3 4 5 6 |
<resources> <string name="app_name">YourAppName</string> <string name="page01">Page 01</string> <string name="page02">Page 02</string> <string name="page03">Page 03</string> </resources> |
サンプルコード2
コンストラクタ パラメータとして
FragmentManager オブジェクトと Lifecycle オブジェクトを使った例です
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 |
//package your.package.name; import androidx.appcompat.app.AppCompatActivity; import androidx.viewpager2.widget.ViewPager2; import android.os.Bundle; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ViewPager2 viewPager2 = findViewById(R.id.view_pager2); TestAdapter adapter = new TestAdapter( getSupportFragmentManager(), getLifecycle()); // set Orientation in your ViewPager2 viewPager2.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL); viewPager2.setAdapter(adapter); } } |
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 |
//package your.package.name; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.lifecycle.Lifecycle; import androidx.viewpager2.adapter.FragmentStateAdapter; import java.util.ArrayList; public class TestAdapter extends FragmentStateAdapter { private final ArrayList<Fragment> fragmentList = new ArrayList<>(); public TestAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) { super(fragmentManager, lifecycle); fragmentList.add(new Fragment01()); fragmentList.add(new Fragment02()); fragmentList.add(new Fragment03()); } @NonNull @Override public Fragment createFragment(int position) { return fragmentList.get(position); } @Override public int getItemCount() { return fragmentList.size(); } } |
他のファイルは同様です
References:
ViewPager2 を使用してフラグメント間をスライドする
ViewPager2
ViewPager から ViewPager2 に移行する