Android重写ViewPager修改滑动灵敏度

使用ViewPager作为一个页面进行切换,里面可以存放很多View,但有时在操作View时不小心滑动一下就有可能跳到下一页,这并不是我们想要的,这里就需要重写ViewPager修改它的滑动条件

效果图


程序目录结构


BTViewPager.java

[java] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. packagecom.example.viewpagerdemo;
  2. importandroid.content.Context;
  3. importandroid.support.v4.view.ViewPager;
  4. importandroid.util.AttributeSet;
  5. importandroid.util.Log;
  6. importandroid.view.MotionEvent;
  7. importandroid.widget.Scroller;
  8. /**
  9. *解决ViewPager滑动过于灵敏,只有滑动距离大于100才滑到另一页
  10. *
  11. *@authorAdministrator
  12. *
  13. */
  14. publicclassBTViewPagerextendsViewPager{
  15. privatestaticfinalStringTAG="dzt_pager";
  16. privatestaticfinalintMOVE_LIMITATION=100;//触发移动的像素距离
  17. privatefloatmLastMotionX;//手指触碰屏幕的最后一次x坐标
  18. privateintmCurScreen;
  19. privateScrollermScroller;//滑动控件
  20. publicBTViewPager(Contextcontext){
  21. super(context);
  22. //TODOAuto-generatedconstructorstub
  23. init(context);
  24. }
  25. publicBTViewPager(Contextcontext,AttributeSetattrs){
  26. super(context,attrs);
  27. //TODOAuto-generatedconstructorstub
  28. init(context);
  29. }
  30. privatevoidinit(Contextcontext){
  31. mScroller=newScroller(context);
  32. mCurScreen=0;//默认设置显示第一个VIEW
  33. }
  34. @Override
  35. publicbooleanonTouchEvent(MotionEventevent){
  36. //TODOAuto-generatedmethodstub
  37. finalintaction=event.getAction();
  38. finalfloatx=event.getX();
  39. switch(action){
  40. caseMotionEvent.ACTION_DOWN:
  41. Log.d(TAG,"[BTViewPager->]onTouchEventACTION_DOWN");
  42. mLastMotionX=x;
  43. break;
  44. caseMotionEvent.ACTION_MOVE:
  45. Log.d(TAG,"[BTViewPager->]onTouchEventACTION_MOVE");
  46. break;
  47. caseMotionEvent.ACTION_UP:
  48. Log.d(TAG,"Item="+getCurrentItem()+"count="
  49. +getChildCount());
  50. if(Math.abs(x-mLastMotionX)<MOVE_LIMITATION){
  51. //snapToDestination();//跳到指定页
  52. snapToScreen(getCurrentItem());
  53. returntrue;
  54. }
  55. break;
  56. default:
  57. break;
  58. }
  59. Log.d(TAG,"[BTViewPager->]onTouchEvent--end");
  60. returnsuper.onTouchEvent(event);
  61. }
  62. @Override
  63. publicvoidcomputeScroll(){
  64. //TODOAuto-generatedmethodstub
  65. Log.d(TAG,"[BTViewPager->]computeScroll");
  66. super.computeScroll();
  67. if(mScroller.computeScrollOffset()){
  68. Log.d(TAG,
  69. "[BTViewPager->]computeScrollx="+mScroller.getCurrX());
  70. scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
  71. invalidate();
  72. }
  73. }
  74. /**
  75. *根据滑动的距离判断移动到第几个视图
  76. */
  77. publicvoidsnapToDestination(){
  78. finalintscreenWidth=getWidth();
  79. finalintdestScreen=(getScrollX()+screenWidth/2)/screenWidth;
  80. Log.d(TAG,"[BTViewPager->]snapToDestinationscreenWidth="
  81. +screenWidth+"destScreen="+destScreen);
  82. snapToScreen(destScreen);
  83. }
  84. /**
  85. *滚动到制定的视图
  86. *
  87. *@paramwhichScreen
  88. *视图下标
  89. */
  90. publicvoidsnapToScreen(intwhichScreen){
  91. //whichScreen=Math.max(0,Math.min(whichScreen,getChildCount()-
  92. //1));
  93. if(getScrollX()!=(whichScreen*getWidth())){
  94. finalintdelta=whichScreen*getWidth()-getScrollX();
  95. Log.d(TAG,"[BTViewPager->]snapToScreen-whichScreen="
  96. +whichScreen+"delta="+delta+"scrollX="
  97. +getScrollX());
  98. mScroller.startScroll(getScrollX(),0,delta,0,
  99. Math.abs(delta)*2);
  100. mCurScreen=whichScreen;
  101. invalidate();
  102. }
  103. }
  104. /**
  105. *用于拦截手势事件的,每个手势事件都会先调用这个方法。Layout里的onInterceptTouchEvent默认返回值是false,
  106. *这样touch事件会传递到childview控件,如果返回false子控件可以响应,否则了控件不响应,这里主要是拦截子控件的响应,
  107. *对ViewGroup不管返回值是什么都会执行onTouchEvent
  108. */
  109. @Override
  110. publicbooleanonInterceptTouchEvent(MotionEventarg0){
  111. //TODOAuto-generatedmethodstub
  112. Log.d(TAG,"[BTViewPager->]onInterceptTouchEvent");
  113. finalintaction=arg0.getAction();
  114. finalfloatx=arg0.getX();
  115. switch(action){
  116. caseMotionEvent.ACTION_DOWN:
  117. Log.d(TAG,"onInterceptTouchEvent---ACTION_DOWN");
  118. mLastMotionX=x;
  119. break;
  120. caseMotionEvent.ACTION_MOVE:
  121. Log.d(TAG,"onInterceptTouchEvent---ACTION_MOVE");
  122. break;
  123. caseMotionEvent.ACTION_UP:
  124. Log.d(TAG,"onInterceptTouchEvent---ACTION_UP");
  125. break;
  126. default:
  127. break;
  128. }
  129. returnsuper.onInterceptTouchEvent(arg0);
  130. }
  131. }
只要是在onTouchEvent的UP中处理滑动的条件

[java] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. if(Math.abs(x-mLastMotionX)<MOVE_LIMITATION){
  2. //snapToDestination();//跳到指定页
  3. snapToScreen(getCurrentItem());
  4. returntrue;
  5. }
只有滑动的距离大于100才进行上下页处理,否则就停在当前页,当前页使用getCurrentItem()获取, 有一点要注意在ViewPager中getChildCount()获取的值是错误的,不清楚是什么原因,在ViewGroup中是有效的,这个可能要查看ViewPager源码才能弄清楚是什么原因,有知道的朋友可以告知我!
完整Demo: http://download.csdn.net/detail/deng0zhaotai/7384637
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值