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

需求:

通过左右滑动刷新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数据表,这样的话,每次滑动后台执行的
动作就是读表然后布局。


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

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





你可能感兴趣的:(Android,Java,ViewPager,GestureDetector)