仕事でViewPagerのループ版を作らせれました。
結構前からあるデザインですが、未だに使われているようなので、作り方をおぼえておかないといけない。
ViewPagerを自分でカスタマイズしても多分できますが、時間の関係でライブラリーから引っ張ってくることにしました。
今回作りたいのは、以下のような画面です。
使用したのは、以下のライブラリーです。
https://github.com/imbryk/LoopingViewPager
画面からはわかないが、スワイプすることにより、写真がループします。
では、実装を起動動線となるMainActivityから
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
package com.example.jiji30000.viewpagersample; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; public class MainActivity extends AppCompatActivity { private static final String TAG = MainActivity.class.getName(); @Override protected void onCreate(Bundle savedInstanceState) { Log.d(TAG, "onCreate"); super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } } |
LoopViewPagerを描画しているだけです。
では、layout
1 2 3 4 5 6 7 8 9 10 11 12 |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/tabhost" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <fragment android:id="@+id/fragment" android:name="com.example.jiji30000.viewpagersample.PageFragment" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> |
FragmentクラスであるPageFragmentを埋め込んでいます。
では、PageFragment
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 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
package com.example.jiji30000.viewpagersample; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.view.ViewPager; import android.util.DisplayMetrics; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; public class PageFragment extends Fragment { private static final String TAG = PageFragment.class.getName(); // スライド用の部品 private LoopViewPager mPager; private int mMargin; private LinearLayout mIndicatorLayout; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Log.d(TAG, "onCreateView"); View view = inflater.inflate(R.layout.viewpager_fragment, container, false); mPager = (LoopViewPager) view.findViewById(R.id.viewpager); mPager.setAdapter(new SamplePagerAdapter(getContext())); mPager.setCurrentItem(0); mPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { Log.d(TAG, "onPageSelected = " + position); // indicator更新 LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); layoutParams.setMargins(mMargin, 0, 0, 0); mIndicatorLayout.removeAllViews(); for (int i = 0; i < SamplePagerAdapter.PAGE_COUNT; ++i) { if (position == i) { View indicatorOn = getActivity().getLayoutInflater().inflate(R.layout.indicator, null); indicatorOn.setLayoutParams(layoutParams); mIndicatorLayout.addView(indicatorOn, layoutParams); } else { View indicatorOff = getActivity().getLayoutInflater().inflate(R.layout.indicator_off, null); indicatorOff.setLayoutParams(layoutParams); mIndicatorLayout.addView(indicatorOff); } } } @Override public void onPageScrollStateChanged(int state) { } }); // indicator mIndicatorLayout = (LinearLayout) view.findViewById(R.id.indicators); LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); DisplayMetrics metrics = getResources().getDisplayMetrics(); mMargin = (int) (metrics.density * 4); layoutParams.setMargins(mMargin, 0, 0, 0); for (int i = 0; i < SamplePagerAdapter.PAGE_COUNT; ++i) { if (i == 0) { View indicatorOn = getActivity().getLayoutInflater().inflate(R.layout.indicator, null); indicatorOn.setLayoutParams(layoutParams); mIndicatorLayout.addView(indicatorOn, layoutParams); } else { View indicatorOff = getActivity().getLayoutInflater().inflate(R.layout.indicator_off, null); indicatorOff.setLayoutParams(layoutParams); mIndicatorLayout.addView(indicatorOff); } } return view; } } |
まずは、LoopViewPagerを初期化、そしてindicatorを変更させるために、
listenerをセットしています。
mPager.setOnPageChangeListener
ここでは、ページが切り替わった時に呼ばれる
public void onPageSelected(int position)
をindicatorを再描画するためのメソッドとして使用しています。
中身はみりゃわかります。
続いて、LoopViewPagerにセットしているadapter
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 |
package com.example.jiji30000.viewpagersample; import android.content.Context; import android.support.v4.view.PagerAdapter; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; public class SamplePagerAdapter extends PagerAdapter{ public static final int PAGE_COUNT = 3; private Context mContext; private static final int RES_IDS[] = new int[]{R.drawable.img1,R.drawable.img2,R.drawable.img3}; SamplePagerAdapter(Context context){ mContext = context; } @Override public int getCount() { return PAGE_COUNT; } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public void destroyItem(ViewGroup collection, int position, Object view) { //ViewPagerに登録していたViewを削除する collection.removeView((View)view); } @Override public Object instantiateItem(ViewGroup container,int position){ LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(mContext.LAYOUT_INFLATER_SERVICE); View view = inflater.inflate(R.layout.content_fragment_page,null); ImageView imageView = (ImageView)view.findViewById(R.id.main_image); imageView.setImageResource(RES_IDS[position]); container.addView(view); return view; } } |
大事なのは、Viewが生成される時に呼ばれる
public Object instantiateItem(ViewGroup container,int position)
です。
まず、定型文としてinflatorを生成
Viewをinflatorとxmlを使用して生成。
xmlにセットされているimageviewに画像をセットする。
container(ViewPagerのView)に先ほど生成したViewをセットする
という感じです。
あとは、destroyItemですか
public void destroyItem(ViewGroup collection, int position, Object view)
不要になったViewをリリースする役目みたいですね。
あとは、ViewPagerにセットしているレイアウトxmlです。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<FrameLayout 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="com.example.jiji30000.viewpagersample.FragmentPage"> <ImageView android:id="@+id/main_image" android:layout_width="match_parent" android:layout_height="wrap_content" android:scaleType="fitXY" /> </FrameLayout> |
単純なimageViewのみがセットされたレイアウトになっています。
今回は、単純な画像だけのpagerですが、Fragmentなどをセットする場合は、
ライブラリー群に書いてある、Actualなんちゃら関数を使わないと、正確な値がとってこれないみたいで、仕事で使った時もそのあたりを使って、ページに対しての正確なpage番号を取得たので、そのあたりはライブラリの中身を見るといいと思います。
最後にgithubのパスを載せます。
https://github.com/jiji4000/android-viewpager/tree/loop_view_pager
全部プルしてください
code
more code
~~~~