【Android开发日记】左右滑动刷新界面的思路记录 ViewPager GestureDetector

来源:互联网 发布:网络道德教育活动方案 编辑:程序博客网 时间:2024/05/11 16:23

需求:

通过左右滑动刷新ViewPager的内容,要求往右前进,往左后退,除非遇到数据两个端点否则不会间断。

记录一下我的处理过程,前后一共试用了4种方法:


方法一:ViewPager(10个page)

左右滑动处理:ViewPager中添加10个page,都是一个Fragment的复用,当滑动到最后一个界面时,跳转到第一个page。实现循环滑动。

数据处理:

内存常驻10组数据。

第一次加载:初次加载10条数据,分别布局到10个page上。

更新数据:每当向右滑动滑动到第10个page时,自动加载新的一组数据。每当向左滑动到第1个page时,加载一组新的数据。

当然,加载的数据可以从网上下载或者从本地数据表或文件加载。

思路介绍:

1.10张page的ViewPage只用在首尾加载数据,中间可以保证流畅滑动加载。

2.使用setCurrentItem();进行跳转,实现循环滑动的效果。即只要有数据,向左向右可以无限拖动。

3,ViewPager滑动时的默认动画是可以看到下一张的缩影的,而我们的数据已经布局到每一个page上了,因此缩影上有数据。

出现的bug:

1.使用setCurrentItem();从最后一张跳到第一张时,不是一下跳到的,而是遍历了从0-9张,可以使用下面的代码来遮盖这个效果,优化动画:

//控制跳转速度public class FixedSpeedScroller extends Scroller {      private int mDuration = 0;        public FixedSpeedScroller(Context context) {          super(context);      }        public FixedSpeedScroller(Context context, Interpolator interpolator) {          super(context, interpolator);      }        @SuppressLint("NewApi")public FixedSpeedScroller(Context context, Interpolator interpolator, boolean flywheel) {          super(context, interpolator, flywheel);      }          @Override      public void startScroll(int startX, int startY, int dx, int dy, int duration) {          super.startScroll(startX, startY, dx, dy, mDuration);      }        @Override      public void startScroll(int startX, int startY, int dx, int dy) {          super.startScroll(startX, startY, dx, dy, mDuration);      }  }//* 设置ViewPager的滑动速度     // *      // * */      private void setViewPagerScrollSpeed( ){          try {              Field mScroller = null;              mScroller = ViewPager.class.getDeclaredField("mScroller");              mScroller.setAccessible(true);               FixedSpeedScroller scroller = new FixedSpeedScroller( vp.getContext( ) );              mScroller.set( vp, scroller);          }catch(NoSuchFieldException e){                        }catch (IllegalArgumentException e){                        }catch (IllegalAccessException e){                        }      }

2.由于是控制在前进或者退后的最后一张加载数据:即向左滑动,index+1,在第10张时更新数据;向右滑动,index-1,在第1张时更新数据。

但是如果你是index+1 到达最后一张,更新了下一组的数据(第2组 10-19),但是这时又往回拖动,希望还是显示的第一组(0-9),就会发现显示的是内存中刚加载的第二组(10-19)。同样,在后退时也存在这样一个bug。

3.10个page太多,占用缓存。


方法二:ViewPager(3个page)

这时请教了群里的少年们得到的方法,谢谢。

使用了3个page的ViewPager,复用同一个Fragment。

左右滑动:

虽然使用了3个page的ViewPager,用户看到的始终是第2个即中间的那个page。

当向左滑动,本来会跳到第3个page,使用setCurrentItem(1);跳回去。当向右滑动,本来会转到第1个page,使用setCurrentItem(1);跳回去。

数据处理:

在使用了setCurrentItem(1);方法后更新数据。


思路:

1.是用户看到的始终是第2个page,这样解决了循环滑动的问题。

bug:

1.滑动page时看到的下一张的缩影是空白的。

2,内存中如果放置一组数据,还是无法预判加载一组新数据后用户的操作。


方法三:ViewPager +  GestureDetector

这时我想利用Gesture是否可以通过用户的手势事先预判用户的滑动方向呢?这样根据手势来决定加载哪一组数据进入内存。

我在方法二的基础上使用了GestureDetector,这时候出现了手势事件处理的冲突问题

Viewpager是子控件, GestureDetector是绑定在父控件上的,改来改去,有时候只有ViewPager拿到手势事件,有时候只有父控件拿到手势事件。

突然我想到,既然能通过手势来判断左右动作,为什么不跳过ViewPager这个梗呢?只使用一个布局,每次通过手势判断更新数据?


方法四: GestureDetector

只使用一个GestureDetector,通过手势判断前进或者后退。

但是数据处理上,一次加载10组数据进内存的办法我放弃了。因为即使使用手势判断,还是有bug,比如说现在显示的10个数据中的组后一组,手势判断知道要前进,那么会加载新的10个数据进内存,这时候如果再后退,会又加载10条旧的数据进内存。

因此我在数据处理上将数据放在SQLite表中,每次手势判断到向左或向右,就去数据表中加载对应的一条数据出来更新布局。实验证明,从数据表中select一条数据,然后即使根据数据再去sd卡上读一张图片,然后将文字和图片布局到界面上,效果还是不错的。现在的手机cpu完全可以应对。

在程序中记录当前的信息编号index以及本地表中最大的信息编号maxindex,然后在合适的时机下载若干组数据到本地存入SQLite数据表,这样的话,每次滑动后台执行的
动作就是读表然后布局。


四种方法中方法四是我现在采用的,当然不一定是最好的处理办法。

写的比较乱,希望对大家有所启发,看不清楚可以在评论中指出,当然如果你有更好的办法请分享给我!





0 0
原创粉丝点击