ViewPager(一屏多页、无限滑动、自动切换)
来源:互联网 发布:如何选钢琴老师 知乎 编辑:程序博客网 时间:2024/06/05 17:23
一、简介
前段时间在腾讯视频中看到一个效果,是一个广告轮播,然后一屏还显示了多页。看着这个效果看着还不错,就自己实现了下。
国际惯例先上效果图,如下:(虽然界面比较简陋,但是功能是全的)
============================分割线========================
二、原理
实现如上效果需要两个功能:一屏多页、无限滑动、自动切换,下边将分别简单的介绍其原理。
1、一屏多页
不限制子View在其范围内。
2、无限滑动
限于文字功底不足,所以举例说明一下。有一个ViewPager,有5页数据{1,2,3,4,5},那么在1前加一页为0,内容和5一样,同时在5后加一页为6,内容和1一样(Adapter中体现);然后在页面切换后判断,如果是0页时跳转到5页,6页时跳转到1页。
3、自动切换
每隔一段时间,切换到下一页
三、实现
(1)让ViewPager的父容器具有android:clipChildren="false"和android:layerType="software"这两个属性,前一句主要意思是不限制子View在其范围内,后一句是启动硬件加速。
(2)ViewPager设置marginLeft和marginRight属性,这两个大小会分别导致左右两边的page显示的大小。
这两步代码如下:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout 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" android:clipChildren="false" android:layerType="software" tools:context="net.arvin.viewpagertransdemo.MainActivity"> <android.support.v4.view.ViewPager android:id="@+id/mPager" android:layout_width="match_parent" android:layout_height="200dp" android:layout_marginLeft="32dp" android:layout_marginRight="32dp" /></RelativeLayout>
(3)创建可循环的Adapter,如下:
import android.support.v4.app.Fragment;import android.support.v4.app.FragmentManager;import android.support.v4.app.FragmentStatePagerAdapter;import net.arvin.viewpagertransdemo.SimpleFragment;import java.util.List;/** * Created by arvin on 2016/8/24 09:52 */public class LoopPagerAdapter extends FragmentStatePagerAdapter { private List<Integer> items; public LoopPagerAdapter(FragmentManager fm, List<Integer> items) { super(fm); this.items = items; } @Override public int getCount() { //比原来的页数多两页,因为在第一页前加;最后一页后也要加一页 return items.size() + 2; } @Override public Fragment getItem(int position) { //将position转化为对应在items的position if (position == items.size() + 1) { //在最后一页的时候显示第一页的内容, position = 0; } else if (position == 0) { //在第一页的时候显示最后一页的内容 position = items.size() - 1; } else { position -= 1; } //显示相应页的内容 return new SimpleFragment(items.get(position)); }}其中SimpleFragment就是作为背景显示传入的颜色值,就不解释了。
(4)设置ViewPager,如下:
mPager = (ViewPager) findViewById(R.id.mPager); mPager.setAdapter(new LoopPagerAdapter(getSupportFragmentManager(), mItems)); mPager.setPageMargin(Utils.dp2px(1)); mPager.setOffscreenPageLimit(mItems.size()); mPager.setCurrentItem(currentPosition); mPager.setOnPageChangeListener(this);setPageMargin这是设置页与页之间的距离;
currentPosition初始化为1,这才是真是的第一页的数据;
其他的都是ViewPager的基本东西,这里就不解释了;
(5)处理页面切换后的逻辑,如下:
@Override public void onPageSelected(int position) { currentPosition = position; if (position == getColors().size() + 1) { currentPosition = 1; isNeedChange = true; } else if (position == 0) { isNeedChange = true; currentPosition = getColors().size(); } else { isNeedChange = false; } } @Override public void onPageScrollStateChanged(int state) { if (state == ViewPager.SCROLL_STATE_IDLE && isNeedChange) { mPager.setCurrentItem(currentPosition, false); } }首先,isNeedChange表示是否需要改变界面,也就是切换页面后position为第一页或者最后一页时就需要改变,其他时候就不需要,因为处于所有页面的中间;
然后,currentPosition表示切换后的真实位置,上边的代码逻辑也很简单,介绍原理时已说明;
最后,在onPageScrollStateChanged中在停止滚动且可以改变界面时,我们就跳转到真实的页面,且不加动画。
(6)自动切换
自动切换,每隔一段时间触发一个事件,可以用Timer,用法也很简单,就不介绍了,因为我们用的不是它;这里使用Handler去实现,然而Handler的使用往往会引起内存泄露
,所以我们需要封装一下,使用弱引用去处理一下,这里也就不详细介绍了,直接上Handler的代码:
public class WeakHandler extends Handler { private WeakReference<IWeakHandler> mCallback; public WeakHandler(IWeakHandler activity) { this.mCallback = new WeakReference<>(activity); } public WeakHandler(Looper looper,IWeakHandler activity){ super(looper); this.mCallback = new WeakReference<>(activity); } @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (mCallback != null) { mCallback.get().handleMessage(msg); } }}然后我们在主界面中,首先初始化一下这个WeakHandler:
mHandler = new WeakHandler(this);这里需要实现一个IweakHandler的接收到消息的回调,收到消息后就应该切换界面,并再次发出一个自动切换的消息:
@Override public void handleMessage(Message msg) { if (msg.what == TRANS_ANIM_CODE) { mPager.setCurrentItem(++currentPosition, true); startTrans(); } }然后我们应该再哪里去发出或者移除自动切换的消息,没错就分别在界面可见和不可见时就行了:
@Override protected void onResume() { super.onResume(); startTrans(); } @Override protected void onPause() { super.onPause(); stopTrans(); } private void startTrans() { mHandler.sendEmptyMessageDelayed(TRANS_ANIM_CODE, TRANS_ANIM_DURING); } private void stopTrans() { mHandler.removeMessages(TRANS_ANIM_CODE); }这样我们就实现了自动切换了,这时候你可能会发现一个体验上的问题,当用户正在操作时,这个收到这个切换消息时,也毅然决然的切换了,让用户觉得怎么回事,我还想慢
慢的看会呢,接下来就来处理这个问题。
(7)在用户操作时不自动切换
正如这个小标题所说,那要怎么做才能不自动切换呢,对,就是在用户触摸到Page的时候就移除掉自动切换的消息,在用户没有触摸到Page的时候就发出自动切换的消息。这时
候就需要我们去重写ViewPager,监听触摸事件,并给出相应的回调,代码也很简单,如下:
public class UserOperateCallbackViewPager extends ViewPager { private IUserOperating mUserOperating; public UserOperateCallbackViewPager(Context context) { super(context); } public UserOperateCallbackViewPager(Context context, AttributeSet attrs) { super(context, attrs); } public void setUserOperating(IUserOperating userOperating) { this.mUserOperating = userOperating; } @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: if (mUserOperating != null) { mUserOperating.userOperating(true); } break; case MotionEvent.ACTION_UP: if (mUserOperating != null) { mUserOperating.userOperating(false); } break; } return super.onTouchEvent(ev); } public interface IUserOperating { void userOperating(boolean isOperating); }}然后我们就用UserOperateCallbackViewPager去替换掉原生的ViewPager,再为新的ViewPager设置一个回调,并处理回调即可:
mPager.setUserOperating(this); @Override public void userOperating(boolean isOperating) { if (isOperating) { stopTrans(); } else { startTrans(); } }这样我们的自动切换的功能就正式完成了。
我们只需要调整布局放到我们的项目中,就能实现比较优雅的界面了。
=========================分割线====================
源码链接
- ViewPager(一屏多页、无限滑动、自动切换)
- ViewPager自动无限循环滑动
- 无限自动滑动的ViewPager
- Android ViewPager 无限循环左右滑动(可自动) 实现
- ViewPager无限循环滑动+自动播放
- ViewPager实现自动无限循环切换
- ViewPager轮播图自动无限循环滑动,手指按住停止滑动
- ViewPager实现无限循环切换和手势滑动效果
- 无限滑动的ViewPager
- viewpager无限左右滑动
- 无限滑动的viewpager
- ViewPager 实现无限滑动
- viewpager无限滑动
- Android ViewPager实现无限循环(2.加入小圆点,优化自动和手动滑动冲突)
- ViewPager无限轮播(真正的左右无限滑动)
- ViewPager自动切换及手动滑动重新计时的问题
- 实现viewPager无限左右滑动
- android viewpager 无限左右滑动
- java 生成 .csv 文件
- AlarmManager 详解
- 测试之路-启程
- 初步认识https与http
- 闭包的应用场景
- ViewPager(一屏多页、无限滑动、自动切换)
- 详解非农数据(非农周提前预热!!!)
- Android中对app应用内存的分配
- android中获取验证码后出现60秒的倒计时
- 验证表单input
- 原来你是这样的NullPointerException
- jQuery动画效果
- Concurrent request scheduling explained
- SQL*PLUS中开启SQL TRACE时报错SP2-0618和SP2-0611的解决方法