源码分析相关面试题
Activity相关面试题
与XMPP相关面试题
与性能优化相关面试题
与登录相关面试题
与开发相关面试题
与人事相关面试题
本文配套视频
今天做项目用ViewPager.setCurrentItem 方法,如果两个页面相聚比较远,就会闪瞎我的钛合金双眼,中间切换大概20个页面,如下所示:
setCurrentItem第二个参数设置false,四不四很简单,直接使用如下代码:
ViewPager.setCurrentItem(position,false);
很不幸的是,使用上面的代码会出现如下效果,扎心了老铁:
从第一题点击切换到第十八题,你会发现页面显示空白,如果从第十个页面切换到第十五个页面没事,平时大家估计没有发现这个bug,一般我们使用ViewPager都是底下5个tab页面,从第一个切换到第五个没事,之前我也以为把第二个参数设置false就行,今天才发现,原来如果当页面比较少的时候,大概十个以内,一般没有问题,如果超过十个页面切换就会出现空白,加载不了数据,扎心了,提出解决方案吧,ViewPager滑动使用的是Scroll,咱们把Scroll的滑动时间duration 设置为0就行。
自定义一个Scroll类,用于控制ViewPager滑动速度:
public class MScroller extends Scroller {
private static final Interpolator sInterpolator = new Interpolator() {
public float getInterpolation(float t) {
t -= 1.0f;
return t * t * t * t * t + 1.0f;
}
};
public boolean noDuration;
public void setNoDuration(boolean noDuration) {
this.noDuration = noDuration;
}
public MScroller(Context context) {
this(context,sInterpolator);
}
public MScroller(Context context, Interpolator interpolator) {
super(context, interpolator);
}
@Override
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
if(noDuration)
//界面滑动不需要时间间隔
super.startScroll(startX, startY, dx, dy, 0);
else
super.startScroll(startX, startY, dx, dy,duration);
}
}
上面代码可知:
1)动态判断页面是否需要滑动,如果不需要滑动,设置滑动时间为0;
为方便使用,定义一个辅助类
public class ViewPageHelper {
ViewPager viewPager;
MScroller scroller;
public ViewPageHelper(ViewPager viewPager) {
this.viewPager = viewPager;
init();
}
public void setCurrentItem(int item){
setCurrentItem(item,true);
}
public MScroller getScroller() {
return scroller;
}
public void setCurrentItem(int item, boolean somoth){
int current=viewPager.getCurrentItem();
//如果页面相隔大于1,就设置页面切换的动画的时间为0
if(Math.abs(current-item)>1){
scroller.setNoDuration(true);
viewPager.setCurrentItem(item,somoth);
scroller.setNoDuration(false);
}else{
scroller.setNoDuration(false);
viewPager.setCurrentItem(item,somoth);
}
}
private void init(){
scroller=new MScroller(viewPager.getContext());
Class<ViewPager>cl=ViewPager.class;
try {
Field field=cl.getDeclaredField("mScroller");
field.setAccessible(true);
//利用反射设置mScroller域为自己定义的MScroller
field.set(viewPager,scroller);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}catch (IllegalAccessException e){
e.printStackTrace();
}
}
}
由上面代码可知:
1)Math.abs(current-item)>1 ,通过数学函数判断页面相隔大于1,就设置页面切换的动画的时间为0。
2)这样每次设置页面的时候,通过 helper 就可以自动选择是否有时间间隔了。
3)但是这样有点麻烦,每次还要手动改,而且使用TabLayout或者ViewPagerIndicator的话,它会自动调用ViewPager的方法,无法使用Helper,所以可以采用自定一个ViewPager,代码如下:
public class SuperViewPager extends ViewPager {
private ViewPageHelper helper;
public SuperViewPager(Context context) {
this(context,null);
}
public SuperViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
helper=new ViewPageHelper(this);
}
@Override
public void setCurrentItem(int item) {
setCurrentItem(item,true);
}
@Override
public void setCurrentItem(int item, boolean smoothScroll) {
MScroller scroller=helper.getScroller();
if(Math.abs(getCurrentItem()-item)>1){
scroller.setNoDuration(true);
super.setCurrentItem(item, smoothScroll);
scroller.setNoDuration(false);
}else{
scroller.setNoDuration(false);
super.setCurrentItem(item, smoothScroll);
}
}
}
至此完美解决了,ViewPager.setCurrentItem切换页面,效果如下:
- 欢迎关注微信公众号,长期推荐技术文章和技术视频
- 微信公众号名称:Android干货程序员
当前内容版权归 JackChan1999 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 JackChan1999 .