版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chennai1101/article/details/83094786
前言
ViewPager可以实现多个界面的左右滑动。
1. ViewPager简单应用
(1) 布局文件
<android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
(2) 适配器,需要继承PagerAdapter类
public static class DemoPageAdapter extends PagerAdapter {
private List<View> mViewList = new ArrayList<>();
public DemoPageAdapter(Context context) {
for (int index = 0; index < 4; index++) {
TextView view = (TextView) View.inflate(context, R.layout.viewpager_text, null);
view.setText("第" + index + "页");
mViewList.add(view);
}
}
// 返回界面数量
@Override
public int getCount() {
return mViewList.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
// 添加界面,一般会添加当前页和左右两边的页面
@Override
public Object instantiateItem(ViewGroup container, int position) {
container.addView(mViewList.get(position));
return mViewList.get(position);
}
// 去除页面
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(mViewList.get(position));
}
}
(3) 设置适配器
ViewPager viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(new DemoPageAdapter(this));
(4) 效果如下
2. OnPageChangeListener监听器
OnPageChangeListener有三个方法
(1) onPageScrolled方法,显示滑动时页面状态。
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
- 手势从左往右滑动,position为前一页面,positionOffset从1到0。
- 手势从右往左滑动,position为当前页面,positionOffset从0到1。
(2) onPageSelected方法,position是被选择页面
public void onPageSelected(int position)
(3) onPageScrollStateChanged方法,
public void onPageScrollStateChanged(int state)
state有三种状态
- SCROLL_STATE_IDLE,静止状态。
- SCROLL_STATE_DRAGGING,开始拖曳。
- SCROLL_STATE_SETTLING,停止拖曳。
3. 循环的ViewPager
如何实现循环的ViewPager,我们需要在边界的时候做一些特殊处理。
扫描二维码关注公众号,回复:
3636224 查看本文章
(1) 在第一个页面之前和最后一个页面之后,分别添加一个界面,这样才能实现循环。
public static class CyclePageAdapter extends PagerAdapter {
private List<View> mViewList = new ArrayList<>();
public CyclePageAdapter(Context context) {
for (int index = 0; index < 4; index++) {
TextView view = (TextView) View.inflate(context, R.layout.viewpager_text, null);
view.setText("第" + index + "页");
mViewList.add(view);
}
}
// 返回界面数量+2
@Override
public int getCount() {
return mViewList.size() + 2;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
View view;
if (position == 0) {
// 第一个界面,选择原来的最后一个界面
view = mViewList.get(mViewList.size() - 1);
} else if (position == mViewList.size() + 1) {
// 最后一个界面,选择原来的第一个界面
view = mViewList.get(0);
} else {
// 原有的依次从0开始
view = mViewList.get(position - 1);
}
// 页面如果重复添加,会发生异常
try {
container.addView(view);
} catch (Exception e) {
}
return view;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// 不在删除页面
}
}
(2) 到达实际边界以后,切换当前页。
final ViewPager viewPager = findViewById(R.id.view_pager);
final PagerAdapter adapter = new CyclePageAdapter(this);
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_IDLE) {
int position = viewPager.getCurrentItem();
if (position == 0) {
// 第一个界面,切换到原来的最后一个界面
viewPager.setCurrentItem(adapter.getCount() - 2, false);
} else if (position == adapter.getCount() - 1) {
// 最后一个界面,切换到原来的第一个界面
viewPager.setCurrentItem(1, false);
}
}
}
});
// 初始页为1
viewPager.setCurrentItem(1);
(3) 效果如下
4. PageTransformer实现个性的切换动画
transformPage(View page, float position)
方法实现不一样的动画,
- 手势从右往左滑动,当前页面position从0->-1,而下一页面position从1->0。
- 手势从左往右滑动,当前页面position为0->1,而前一页面position从-1->0。
定义一个动画,前一页面左右移动,而后一页面位置不变但伸缩显示。
private class DemoPageTransformer implements ViewPager.PageTransformer {
@Override
public void transformPage(View page, float position) {
if (position < -1) {
page.setAlpha(0);
} else if (position <= 0) {
// 左右移动,并且移除时变透明
page.setAlpha(1 + position);
} else if (position < 1) {
// 去除左右移动效果
page.setTranslationX(-page.getWidth() * position);
// 进入时变大,移除时变小
page.setScaleX(1 - position/2);
page.setScaleY(1 - position/2);
page.setAlpha(1 - position);
} else {
page.setAlpha(0);
}
}
}
效果如下
5. 自定义广告页
广告页长被用于首页,可以自己切换,也可以手动切换。
使用ViewPager实现广告页,主要是要判断是否在手动切换,可以添加OnPageChangeListener来判断。
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
private boolean mDragging = false;
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_IDLE && mDragging) {
mHandler.sendEmptyMessageDelayed(MOVE_TO_NEXT, 3000);
mDragging = false;
} else if (state == ViewPager.SCROLL_STATE_DRAGGING){
mHandler.removeMessages(MOVE_TO_NEXT);
mDragging = true;
}
}
});
mHandler.sendEmptyMessageDelayed(MOVE_TO_NEXT, 3000);
Handler类处理自动切换事件
private static final int MOVE_TO_NEXT = 1;
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == MOVE_TO_NEXT) {
int item = mViewPager.getCurrentItem();
if (++item >= mAdapter.getCount()) {
item = 0;
}
mViewPager.setCurrentItem(item);
mHandler.sendEmptyMessageDelayed(MOVE_TO_NEXT, 3000);
}
}
};