ループできる ViewPager です。ちゃんと作ってないので以下の制限があります。
- ページ数が 3の倍数じゃないといけない(時間がなくて対応してない)
- 連続ページ切り替え(スワイプ後のスクロールが終わる前にさらにスワイプ)に対応してない
- わかんないけどなんかあるかも
ポイントは isViewFromObject() を駆使することと、ViewPager を extends して onLayout で位置を戻すことです。
public class MainActivity extends Activity {
private ViewPager mViewPager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mPagerAdapter = new MyPagerAdapter(this);
mViewPager = (ViewPager) findViewById(R.id.viewpager);
mViewPager.setOffscreenPageLimit(2);
mViewPager.setAdapter(mPagerAdapter);
mViewPager.setOnPageChangeListener(mPagerAdapter);
mViewPager.setCurrentItem(1, false);
}
private MyPagerAdapter mPagerAdapter;
private class MyPagerAdapter extends PagerAdapter implements ViewPager.OnPageChangeListener {
/**
* from 0 to 2
*/
int focusedPosition = 0;
/**
* from 0 to PAGE_NUM -1
*/
int contentPosition = 0;
/**
* number of pages (3x)
*/
int PAGE_NUM = 9;
Context mContext;
LayoutInflater mInflater;
public MyPagerAdapter(Context context) {
mContext = context;
mInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return 3;
}
SparseArray<View> mViews = new SparseArray<View>();
@Override
public Object instantiateItem(ViewGroup container, int position) {
int newPosition = calcContentPosition(position);
View view = createContent(newPosition);
container.addView(view, 0);
mViews.put(position, view);
view.setTag(position);
// return view;
return Integer.valueOf(position);
}
@Override
public boolean isViewFromObject(View view, Object object) {
int index = (Integer) view.getTag();
int position = (Integer) object;
int newPosition = (position + contentPosition) % 3;
return newPosition == index;
}
/**
* create content's view
*
* @param position
* from 0 to PAGE_NUM - 1
* @return
*/
private View createContent(int position) {
View view = mInflater.inflate(R.layout.list, null, false);
updateContent(view, position);
return view;
}
/**
* update content's view
*
* @param view
* @param position
* from 0 to PAGE_NUM -1
*/
private void updateContent(View view, int position) {
ArrayAdapter<String> adapter = new ArrayAdapter<String>(mContext, android.R.layout.simple_list_item_1,
createList(position));
ListView listView = (ListView) view.findViewById(R.id.list);
listView.setAdapter(adapter);
listView.setScrollingCacheEnabled(false);
}
private List<String> createList(int index) {
List<String> list = new ArrayList<String>();
for (int i = 0; i < 50; i++) {
list.add(index + " *************************** " + index + ":" + (i + 1));
}
return list;
}
/**
* get position of content
*
* @param position
* from 0 to 2
* @return content position (from 0 to PAGE_NUM - 1)
*/
private int calcContentPosition(int position) {
int offset = position - 1;
int newPosition = contentPosition + offset;
if (newPosition < 0) {
newPosition = PAGE_NUM - 1;
} else {
newPosition = newPosition % PAGE_NUM;
}
return newPosition;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
int count = mViewPager.getChildCount();
int index = (Integer) object;
for (int i = 0; i < count; i++) {
View v = mViewPager.getChildAt(i);
if (isViewFromObject(v, Integer.valueOf(index))) {
container.removeView(v);
break;
}
}
}
/**
* update specified view's content
*
* @param index
* 0 or 2
*/
void updateContents(int index) {
int count = mViewPager.getChildCount();
for (int i = 0; i < count; i++) {
View v = mViewPager.getChildAt(i);
if (isViewFromObject(v, Integer.valueOf(index))) {
final int newPosition = calcContentPosition(index);
updateContent(v, newPosition);
break;
}
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
focusedPosition = position;
}
@Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_IDLE) {
handlePageScrollStateChangedToIdle();
}
}
private void handlePageScrollStateChangedToIdle() {
switch (focusedPosition) {
case 0:
// scroll to previous page
if ((--contentPosition) < 0) {
contentPosition = PAGE_NUM - 1;
}
updateContents(0);
break;
case 2:
// scroll to next page
contentPosition = (++contentPosition) % PAGE_NUM;
updateContents(2);
break;
default:
break;
}
}
}
}
public class MyViewPager extends ViewPager {
public MyViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if(getCurrentItem() != 1) {
setCurrentItem(1, false);
}
}
}
res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<com.sample.viewpager.MyViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
res/layout/list.xml
<?xml version="1.0" encoding="utf-8"?>
<ListView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:cacheColorHint="#00000000" />
It doesn't work when I put a methode
返信削除@Override
public float getPageWidth(int position) {
return 0.4f;
}
in MyPagerAdapter class
And also how can i change it all for fragment instead of Views
返信削除I have the same problem :(
返信削除