Android面试题-终极解决ViewPager.setCurr
2017-05-10 本文已影响6623人
小怪兽打葫芦娃
自定义控件
- 一分钟实现贴纸功能
- 一分钟实现TextView高亮
- 一分钟实现新手引导页
- 一分钟实现ViewPager卡片
- 一分钟实现轮播图
- 一分钟实现GridView拖拽
- 一分钟实现底部导航栏
- 一分钟实现底部FragmentTabhost
- 一分钟实现多张图片选择
- 一分钟实现仿美拍直播的点赞动画
- 一分钟实现高仿今日头条视频列表
- 一分钟实现购物车加减控件
- 一分钟实现省市县三级联动
- 一分钟实现二维码生成和扫描
- 一分钟实现沉浸式状态栏
- 一分钟实现图片裁剪
- 一分钟实现视频弹幕
- 一分钟实现图片缩放
- 一分钟实现旋转选择器
- 一分钟实现ofo小黄车的引导界面
- 一分钟实现自定义ImageView外貌
- 一分钟实现向左拖拽跳转详情页
- 一分钟实现QQ首页动画特效
- 一分钟实现ViewPager上下滑动
联网
工具
数据库
源码分析相关面试题
Activity相关面试题
- 保存Activity的状态
- 深刻剖析activity启动模式(一)
- 深刻剖析activity启动模式(二)
- 深刻剖析activity启动模式(三)
- Activity Task和Process之间的关系
- 源码分析service开启Activity抛异常?activity不会抛异常
- Activity优雅退出
- onCreate源码分析
Service相关面试题
与XMPP相关面试题
与性能优化相关面试题
与登录相关面试题
与开发相关面试题
- 迭代开发的时候如何向前兼容新旧接口
- 手把手教你如何解决as jar包冲突
- context的原理分析
- 解决ViewPager.setCurrentItem中间很多页面切换方案
- 字体适配
- 软键盘适配
- 机型适配,例如三星、小米、华为、魅族等
- CardView 设置水波纹效果
与人事相关面试题
本文配套视频
今天做项目用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干货程序员