Android
ViewPager
サーチ…
前書き
ViewPagerはレイアウトマネージャーで、ユーザーがデータのページを左右にめくることができます。これは、ほとんどの場合、各ページのライフサイクルを提供し管理するための便利な方法であるフラグメントと組み合わせて使用されます。
備考
ViewPagerの使い方について注意する重要な点は、 FragmentPagerAdapter
とFragmentStatePagerAdapter
2つの異なるバージョンがあることです。
FragmentPagerAdapterまたはFragmentStatePagerAdapterを持つandroid.app.Fragment
ネイティブフラグメントを使用している場合は、アダプタのv13サポートライブラリバージョン(つまり、 android.support.v13.app.FragmentStatePagerAdapter
を使用する必要があります。
FragmentPagerAdapterまたはFragmentStatePagerAdapterを持つandroid.support.v4.app.Fragment
サポートライブラリのフラグメントを使用している場合は、アダプタのv4サポートライブラリバージョン(つまり、 android.support.v4.app.FragmentStatePagerAdapter
を使用する必要があります。
フラグメントによる基本ViewPagerの使用法
ViewPager
では、アクティビティ内に複数のフラグメントを表示することができます。これらのフラグメントは、左または右にフリップすることでナビゲートできます。 ViewPager
は、 PagerAdapter
を使用してビューまたはフラグメントのフィードである必要があります。
ただし、 FragmentPagerAdapter
とFragmentStatePagerAdapter
Fragmentを使用する場合に最も便利な2つの具体的な実装があります。フラグメントを初めてインスタンス化する必要がある場合、インスタンス化が必要な各位置に対してgetItem(position)
が呼び出されます。 getCount()
メソッドは総ページ数を返します。そのため、 ViewPager
表示する必要があるフラグメントの数を認識します。
FragmentPagerAdapter
とFragmentStatePagerAdapter
両方は、 ViewPager
が表示する必要があるフラグメントのキャッシュを保持します。デフォルトでは、 ViewPager
は現在表示されているFragmentに対応するFragmentを最大3つ、右と左のFragmentを最大で3つ保存しようとします。また、 FragmentStatePagerAdapter
は各フラグメントの状態を保持します。
両方の実装は、あなたが見ることができるようにあなたがそれらの静的な数を持つの断片のリストを代わりに保つので、もしあなたのフラグメントは、その位置を維持すると仮定していることに注意してくださいgetItem()
メソッドは、サブクラスを作成する必要がありますPagerAdapter
少なくともinstantiateItem()
、 destroyItem()
およびgetItemPosition()
メソッドをオーバーライドします。
基本的な例で説明したように、レイアウトにViewPagerを追加するだけです :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout>
<android.support.v4.view.ViewPager
android:id="@+id/vpPager">
</android.support.v4.view.ViewPager>
</LinearLayout>
次に、アダプターの各ページに表示するページ数とフラグメント数を決定するアダプターを定義します。
public class MyViewPagerActivity extends AppCompatActivity {
private static final String TAG = MyViewPagerActivity.class.getName();
private MyPagerAdapter mFragmentAdapter;
private ViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.myActivityLayout);
//Apply the Adapter
mFragmentAdapter = new MyPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.view_pager);
mViewPager.setAdapter(mFragmentAdapter);
}
private class MyPagerAdapter extends FragmentPagerAdapter{
public MyPagerAdapter(FragmentManager supportFragmentManager) {
super(supportFragmentManager);
}
// Returns the fragment to display for that page
@Override
public Fragment getItem(int position) {
switch(position) {
case 0:
return new Fragment1();
case 1:
return new Fragment2();
case 2:
return new Fragment3();
default:
return null;
}
}
// Returns total number of pages
@Override
public int getCount() {
return 3;
}
}
}
android.app.Fragment
を使用している場合、この依存関係を追加する必要があります:
compile 'com.android.support:support-v13:25.3.1'
android.support.v4.app.Fragment
を使用している場合、この依存関係を追加する必要があります:
compile 'com.android.support:support-fragment:25.3.1'
ViewPagerとTabLayout
TabLayout
を使用して簡単にナビゲーションをTabLayout
ことができます。
TabLayout.newTab()
メソッドを使用してアダプタ内の各フラグメントのタブを設定できますが、このタスクにはTabLayout.setupWithViewPager()
というもう1つの便利で簡単なメソッドがあります。
このメソッドは、 ViewPager
たびにViewPager
関連付けられているアダプタの内容に従ってタブを作成および削除することによって同期されます。
また、ユーザーがページをめくるたびに、対応するタブが選択されるようにコールバックを設定します。
レイアウトを定義するだけです
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout>
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
app:tabMode="scrollable" />
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1" />
</LinearLayout>
次に、 FragmentPagerAdapter
を実装し、それをViewPager
適用します。
public class MyViewPagerActivity extends AppCompatActivity {
private static final String TAG = MyViewPagerActivity.class.getName();
private MyPagerAdapter mFragmentAdapter;
private ViewPager mViewPager;
private TabLayout mTabLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.myActivityLayout);
// Get the ViewPager and apply the PagerAdapter
mFragmentAdapter = new MyPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.view_pager);
mViewPager.setAdapter(mFragmentAdapter);
// link the tabLayout and the viewpager together
mTabLayout = (TabLayout) findViewById(R.id.tab_layout);
mTabLayout.setupWithViewPager(mViewPager);
}
private class MyPagerAdapter extends FragmentPagerAdapter{
public MyPagerAdapter(FragmentManager supportFragmentManager) {
super(supportFragmentManager);
}
// Returns the fragment to display for that page
@Override
public Fragment getItem(int position) {
switch(position) {
case 0:
return new Fragment1();
case 1:
return new Fragment2();
case 2:
return new Fragment3();
default:
return null;
}
}
// Will be displayed as the tab's label
@Override
public CharSequence getPageTitle(int position) {
switch(position) {
case 0:
return "Fragment 1 title";
case 1:
return "Fragment 2 title";
case 2:
return "Fragment 3 title";
default:
return null;
}
}
// Returns total number of pages
@Override
public int getCount() {
return 3;
}
}
}
PreferenceFragmentを持つViewPager
最近まで、 android.support.v4.app.FragmentPagerAdapter
を使用すると、FragmentPagerAdapterで使用されるFragmentの1つとしてPreferenceFragment
の使用が妨げられます。
サポートv7ライブラリの最新バージョンには、ViewPagerとv4バージョンのFragmentPagerAdapterで動作するPreferenceFragmentCompat
クラスが追加されました。
PreferenceFragmentCompat
を拡張するフラグメントの例:
import android.os.Bundle;
import android.support.v7.preference.PreferenceFragmentCompat;
import android.view.View;
public class MySettingsPrefFragment extends PreferenceFragmentCompat {
public MySettingsPrefFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.fragment_settings_pref);
}
@Override
public void onCreatePreferences(Bundle bundle, String s) {
}
}
このフラグメントは、 android.support.v4.app.FragmentPagerAdapter
サブクラスで使用できます。
private class PagerAdapterWithSettings extends FragmentPagerAdapter {
public PagerAdapterWithSettings(FragmentManager supportFragmentManager) {
super(supportFragmentManager);
}
@Override
public Fragment getItem(int position) {
switch(position) {
case 0:
return new FragmentOne();
case 1:
return new FragmentTwo();
case 2:
return new MySettingsPrefFragment();
default:
return null;
}
}
// .......
}
ViewPagerを追加する
依存関係の下でアプリケーションのbuild.gradle
ファイルに次の依存関係が追加されていることを確認してください。
compile 'com.android.support:support-core-ui:25.3.0'
次に、 ViewPager
をアクティビティレイアウトに追加します。
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
次に、 PagerAdapter
定義します。
public class MyPagerAdapter extends PagerAdapter {
private Context mContext;
public CustomPagerAdapter(Context context) {
mContext = context;
}
@Override
public Object instantiateItem(ViewGroup collection, int position) {
// Create the page for the given position. For example:
LayoutInflater inflater = LayoutInflater.from(mContext);
ViewGroup layout = (ViewGroup) inflater.inflate(R.layout.xxxx, collection, false);
collection.addView(layout);
return layout;
}
@Override
public void destroyItem(ViewGroup collection, int position, Object view) {
// Remove a page for the given position. For example:
collection.removeView((View) view);
}
@Override
public int getCount() {
//Return the number of views available.
return numberOfPages;
}
@Override
public boolean isViewFromObject(View view, Object object) {
// Determines whether a page View is associated with a specific key object
// as returned by instantiateItem(ViewGroup, int). For example:
return view == object;
}
}
最後に、アクティビティでViewPager
を設定します:
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.viewpager);
viewPager.setAdapter(new MyPagerAdapter(this));
}
}
ドットインジケータ付きのViewPager
私たちが必要とするのは、 ViewPager 、 TabLayout 、および選択されたデフォルトドットと2つのドロウアブルです。
まず、画面レイアウトにTabLayout
を追加し、それをViewPager
接続する必要がViewPager
ます。私たちは2つの方法でこれを行うことができます:
ViewPagerのネストされたTabLayout
<android.support.v4.view.ViewPager
android:id="@+id/photos_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.v4.view.ViewPager>
この場合、
TabLayout
は自動的にViewPager
に接続されViewPager
が、TabLayout
はViewPager
横にViewPager
、上には表示されません。
別々のTabLayout
<android.support.v4.view.ViewPager
android:id="@+id/photos_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<android.support.design.widget.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
この場合、
TabLayout
どこにでも置くことができますが、TabLayout
とプログラムでViewPager
を接続するTabLayout
がViewPager
ます
ViewPager pager = (ViewPager) view.findViewById(R.id.photos_viewpager);
PagerAdapter adapter = new PhotosAdapter(getChildFragmentManager(), photosUrl);
pager.setAdapter(adapter);
TabLayout tabLayout = (TabLayout) view.findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(pager, true);
レイアウトを作成したら、私たちは点を準備する必要があります。そこで、 selected_dot.xml
、 default_dot.xml
、およびtab_selector.xml
3つのファイルを作成します。
selected_dot.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape
android:innerRadius="0dp"
android:shape="ring"
android:thickness="8dp"
android:useLevel="false">
<solid android:color="@color/colorAccent"/>
</shape>
</item>
</layer-list>
default_dot.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape
android:innerRadius="0dp"
android:shape="ring"
android:thickness="8dp"
android:useLevel="false">
<solid android:color="@android:color/darker_gray"/>
</shape>
</item>
</layer-list>
tab_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/selected_dot"
android:state_selected="true"/>
<item android:drawable="@drawable/default_dot"/>
</selector>
これで、xmlレイアウトのTabLayout
にコードを3行追加するだけで済みます。
app:tabBackground="@drawable/tab_selector"
app:tabGravity="center"
app:tabIndicatorHeight="0dp"
セットアップOnPageChangeListener
選択したページの変更をリッスンする必要がある場合は、 ViewPager.OnPageChangeListener
リスナーを実装できます。
viewPager.addOnPageChangeListener(new OnPageChangeListener() {
// This method will be invoked when a new page becomes selected. Animation is not necessarily complete.
@Override
public void onPageSelected(int position) {
// Your code
}
// This method will be invoked when the current page is scrolled, either as part of
// a programmatically initiated smooth scroll or a user initiated touch scroll.
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// Your code
}
// Called when the scroll state changes. Useful for discovering when the user begins
// dragging, when the pager is automatically settling to the current page,
// or when it is fully stopped/idle.
@Override
public void onPageScrollStateChanged(int state) {
// Your code
}
});