`
445822357
  • 浏览: 738926 次
文章分类
社区版块
存档分类
最新评论

Android重写ViewPager修改滑动灵敏度

 
阅读更多

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

效果图


程序目录结构


BTViewPager.java

  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中处理滑动的条件

  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
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics