[Android]无限循环ViewPager
来源:互联网 发布:linux 迅雷远程下载 编辑:程序博客网 时间:2024/04/28 21:51
首先,我们先来看看平常时,我们是如何使用ViewPager的。
布局文件:activity_main.xml
<?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" tools:context="com.xiaoyan.xiejinxiong.unlimitedslideviewpager.MainActivity"> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent" /></RelativeLayout>适配器代码:MyViewPagerAdapter.java
package com.xiaoyan.xiejinxiong.unlimitedslideviewpager;import android.support.v4.view.PagerAdapter;import android.view.View;import android.view.ViewGroup;import java.util.List;/** * Created by xiejinxiong on 2016/6/3. */public class MyViewPagerAdapter extends PagerAdapter { private List<View> mListViews; public MyViewPagerAdapter(List<View> mListViews) { this.mListViews = mListViews; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView(mListViews.get(position));//删除页卡 } @Override public Object instantiateItem(ViewGroup container, int position) { //实例化页卡 container.addView(mListViews.get(position), 0);//添加页卡 return mListViews.get(position); } @Override public int getCount() { return mListViews.size();//返回页卡的数量 } @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == arg1;//官方提示这样写 }}
主页面:MainActivity.java
package com.xiaoyan.xiejinxiong.unlimitedslideviewpager;import android.app.Activity;import android.support.v4.view.ViewPager;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.ImageView;import java.util.ArrayList;import java.util.List;/** * @author xiejinxiong */public class MainActivity extends Activity { private ViewPager viewPager; /**ViewPager适配器*/ private MyViewPagerAdapter myViewPagerAdapter; /** 存储ViewPager需要显示的View */ private List<View> list; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initUI(); } /** * 初始化UI */ private void initUI() { viewPager = (ViewPager) findViewById(R.id.viewpager); //初始化图片数据 list = new ArrayList<>(); ImageView imageView = new ImageView(this); imageView.setImageResource(R.drawable.pic1); list.add(imageView); ImageView imageView2 = new ImageView(this); imageView2.setImageResource(R.drawable.pic2); list.add(imageView2); ImageView imageView3 = new ImageView(this); imageView3.setImageResource(R.drawable.pic3); list.add(imageView3); myViewPagerAdapter = new MyViewPagerAdapter(list); viewPager.setAdapter(myViewPagerAdapter); }}
由以上代码便可以制作一个可滑动,具有三个页面的ViewPager:
(- -没弄Gif,就勉强看看图片吧)
由上面的代码,我们可以很清楚的看出,布局文件与主页面的功能并不多,只是定义初始化ViewPager以及填充数据,具体对于ViewPager的页面加载操作大部分都需要在ViewPager的适配器中写,因此,假如我们想制作一个无限滑动的Viewpager,更多的也是在ViewPager的适配器中进行修改。
首先,我们先看看,为何这个ViewPager只能滑动三个页面?
public int getCount() { return mListViews.size();//返回页卡的数量 }无疑,大部分原因出现在这里,因此,我们需要在这里进行修改,我们将其修改为一个最大值,那便是Integer.MAX_VALUE
@Override public int getCount() { return Integer.MAX_VALUE; }然后,我们再对程序进行运行:
我们会发现,假如我们只是滑动前面两个是完全没有问题的,但是滑动到第三个就会报错:
java.lang.IndexOutOfBoundsException: Invalid index 3, size is 3 at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251) at java.util.ArrayList.get(ArrayList.java:304) at com.xiaoyan.xiejinxiong.unlimitedslideviewpager.MyViewPagerAdapter.instantiateItem(MyViewPagerAdapter.java:29) at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:943) at android.support.v4.view.ViewPager.populate(ViewPager.java:1157) at android.support.v4.view.ViewPager.populate(ViewPager.java:1025) at android.support.v4.view.ViewPager$3.run(ViewPager.java:254) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725) at android.view.Choreographer.doCallbacks(Choreographer.java:555) at android.view.Choreographer.doFrame(Choreographer.java:524) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711) at android.os.Handler.handleCallback(Handler.java:615) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4745) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) at dalvik.system.NativeStart.main(Native Method)
那是因为我们设置geiCount()为无限大,也就是我们告诉ViewPager,我们具有着无限多个页面,因此当它滑动到第三个的时候,便开始预加载第四个,但mListViews.size()只有三个,因此报下标越界错误,错误在这行:
container.addView(mListViews.get(position), 0);//添加页卡因此,我们需要对该行进行修改:
mListViews.get(position),我们只是需要获得需要显示的View,也就是,当position为3的时候,我们需要获得mListViews.get(0)的View,当position为4的时候,我们需要获得mListViews.get(1)的View,以此类推,我们可以将该适配器中的mListViews.get(position)全部改为mListViews.get(position% mListViews.size()),运行:
由此,你可以一直向左划,是可以不断地滑动的,但是,假如你是向右划一下的话,就会报错:
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first. at android.view.ViewGroup.addViewInner(ViewGroup.java:3378) at android.view.ViewGroup.addView(ViewGroup.java:3249) at android.support.v4.view.ViewPager.addView(ViewPager.java:1413) at android.view.ViewGroup.addView(ViewGroup.java:3194) at com.xiaoyan.xiejinxiong.unlimitedslideviewpager.MyViewPagerAdapter.instantiateItem(MyViewPagerAdapter.java:29) at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:943) at android.support.v4.view.ViewPager.populate(ViewPager.java:1125) at android.support.v4.view.ViewPager.populate(ViewPager.java:1025) at android.support.v4.view.ViewPager$3.run(ViewPager.java:254) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725) at android.view.Choreographer.doCallbacks(Choreographer.java:555) at android.view.Choreographer.doFrame(Choreographer.java:524) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711) at android.os.Handler.handleCallback(Handler.java:615) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4745) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) at dalvik.system.NativeStart.main(Native Method)报错代码:
container.addView(mListViews.get(position% mListViews.size()), 0);//添加页卡大概意思就是说mListViews.get(position% mListViews.size())所获得的View已经有parent,但是,现在你现在又将该View添加到parent中,这样是不行的,需要在parent添加该View之前将其remove掉。
也就是说,我们需要在 container.addView(mListViews.get(position% mListViews.size()), 0);之前,先使用container remove掉之前的mListViews.get(position% mListViews.size())的View。
需要实例化页卡代码改为:
@Override public Object instantiateItem(ViewGroup container, int position) { //实例化页卡 container.removeView(mListViews.get(position % mListViews.size())); container.addView(mListViews.get(position% mListViews.size()), 0);//添加页卡 return mListViews.get(position% mListViews.size()); }运行:
在这时,你可以一直向左划,是可以不断地滑动的,但是,假如你是向右划的话,虽然不会报错,但是会出现一件很奇怪的事情,图片消失了,背景变得空白,后来,我输出 Log.v("NUM","container.getChildCount():"+container.getChildCount());
发现,在往左划的时候,并不会加载之前View,而是一直删除,因此,假如我们需要保证一定可以显示mListViews里面的全部View,那么,我们需要保证container.getChildCount()==mListViews.size()的时候,才开始删除mListViews.get(position % mListViews.size(),于是,需要实例化页卡代码改为:
@Override public Object instantiateItem(ViewGroup container, int position) { //实例化页卡 if (container.getChildCount() == mListViews.size()) { container.removeView(mListViews.get(position % mListViews.size())); } container.addView(mListViews.get(position% mListViews.size()), 0);//添加页卡 return mListViews.get(position% mListViews.size()); }
但是,这样居然会报错:
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first. at android.view.ViewGroup.addViewInner(ViewGroup.java:3378) at android.view.ViewGroup.addView(ViewGroup.java:3249) at android.support.v4.view.ViewPager.addView(ViewPager.java:1413) at android.view.ViewGroup.addView(ViewGroup.java:3194) at com.xiaoyan.xiejinxiong.unlimitedslideviewpager.MyViewPagerAdapter.instantiateItem(MyViewPagerAdapter.java:29) at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:943) at android.support.v4.view.ViewPager.populate(ViewPager.java:1125) at android.support.v4.view.ViewPager.populate(ViewPager.java:1025) at android.support.v4.view.ViewPager$3.run(ViewPager.java:254) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725) at android.view.Choreographer.doCallbacks(Choreographer.java:555) at android.view.Choreographer.doFrame(Choreographer.java:524) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711) at android.os.Handler.handleCallback(Handler.java:615) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4745) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) at dalvik.system.NativeStart.main(Native Method)后来,我百度谷歌了一下,发现把destroyItem方法修改一下即可:
@Override public void destroyItem(ViewGroup container, int position, Object object) {//删除页卡 container.removeView(container);//删除页卡 }于是,该ViewPager可以一直向左滑动,往右滑动也不会出现错误。
但是,还是出现一个小问题,那就是第一页不能往右划。
这样问题,只需要在主页面修改默认显示页数即可,将其改为:
viewPager.setCurrentItem(525);这里的525可以随意修改,只要是 mListViews.size()的倍数,并且足够大就行,因为假如设置为525,向右滑动525次便可以滑到尽头,(- -但是一般没人这么无聊吧)
源码:http://download.csdn.net/detail/u011596810/9540534
- Android无限循环ViewPager
- [Android]无限循环ViewPager
- android viewpager轮播图无限循环
- android 实现无限循环viewpager
- Android 无限循环ViewPager报错跳坑。
- Android 无限循环ViewPager报错跳坑。
- Android无限循环滚动ViewPager
- android ViewPager+Fragment封装无限循环ViewPager
- android viewpager 无限循环实现gallery 效果
- Android ViewPager 实现无限循环滑动
- Android中ViewPager无限循环实现方法
- android viewpager 实现左右无限循环
- android ViewPager+FragmentStatePagerAdapter无限循环FragmentStatePagerAdapter
- 【Android】ViewPager实现无限循环滚动
- Android ViewPager实现无限循环滑动
- android 自定义Viewpager实现无限循环
- Android 开源组件无限循环ViewPager
- android viewpager实现无限循环自动滚动
- java数字的格式化
- Javadoc转换chm帮助文档的四种方法总结
- python 2.7 访问 MS sql
- linux 分析 ptrace()
- 数学问题题目连接
- [Android]无限循环ViewPager
- HashMap源码分析
- 97. Interleaving String【H】【73】
- 自定义TextView超过一行换行居中
- 简谈struct 运算符重载
- Windows 7运行命令大全,小编整理了常用的45个Win7运行命令分享给大家:
- KODI插件制作
- 5种开源协议
- 阿里云官方架构图标