Scroller(四)——实现拉动后回弹的布局

PS:

该篇博客已经deprecated,不再维护,详情请参见 

站在源码的肩膀上全解Scroller工作机制

 http://blog.csdn.NET/lfdfhl/article/details/53143114

 

MainActivity如下:

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. package cc.testscroller2;  
  2.   
  3. import android.os.Bundle;  
  4. import android.app.Activity;  
  5.   
  6. public class MainActivity extends Activity {  
  7.   
  8.     @Override  
  9.     protected void onCreate(Bundle savedInstanceState) {  
  10.         super.onCreate(savedInstanceState);  
  11.         setContentView(R.layout.main);  
  12.     }  
  13.   
  14.       
  15. }  

 

BounceableLinearLayout如下:

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. package cc.testscroller2;  
  2. import android.content.Context;    
  3. import android.util.AttributeSet;    
  4. import android.view.GestureDetector;    
  5. import android.view.MotionEvent;    
  6. import android.widget.LinearLayout;    
  7. import android.widget.Scroller;    
  8. /** 
  9.  * 总体思路: 
  10.  * 处理View的Touch事件,即重写onTouchEvent()方法: 
  11.  * 当手指抬起时将其回到原点,其余情况交给GestureDetector处理. 
  12.  *  
  13.  * 在GestureDetector中重点是覆写onScroll()方法.在该方法中得到 
  14.  * Y方向滑动的距离,从而设置 mScroller.startScroll()方法,准备滑动. 
  15.  * 随之刷新界面invalidate()从而执行方法computeScroll(). 
  16.  * 在computeScroll()方法中调用 scrollTo()方法实现真正的滑动. 
  17.  *  
  18.  * 注意事项: 
  19.  * 1 scrollTo()方法的参数: 
  20.  *   scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); 
  21.  *   并且在此之后也要调用postInvalidate()进行刷新  
  22.  *  
  23.  *  
  24.  * 方法说明: 
  25.  * 1 mScroller.getFinalX(Y)() 
  26.  *   The final X(Y) offset as an absolute distance from the origin. 
  27.  *   返回滚动结束位置(得到当前X(Y)距离原始位置的值).仅针对"fling"滚动有效. 
  28.  *   也就是说该方法是针对滚动结束而言的. 
  29.  *    
  30.  *   坐标方向: 
  31.  *   X方向的距离,正数向左,负数向右 
  32.  *   Y方向的距离,正数向上,负数向下 
  33.  *    
  34.  * 2 mScroller.getCurrX(Y)() 
  35.  *   The new X offset as an absolute distance from the origin. 
  36.  *   The new Y offset as an absolute distance from the origin. 
  37.  *   返回当前滚动 X(Y)方向的偏移 
  38.  *   也就是说该方法是针对滚动中而言的. 
  39.  *    
  40.  *   坐标方向: 
  41.  *   X方向的距离,正数向左,负数向右 
  42.  *   Y方向的距离,正数向上,负数向下 
  43.  *    
  44.  *    
  45.  * 3 startScroll(int startX, int startY, int dx, int dy, int duration) 
  46.  *   第一,二个参数起始位置;第三,四个滚动的偏移量;第五个参数持续时间 
  47.  *    
  48.  * 
  49.  */  
  50. public class BounceableLinearLayout extends LinearLayout {    
  51.     private Scroller mScroller;    
  52.     private GestureDetector mGestureDetector;    
  53.         
  54.     public BounceableLinearLayout(Context context) {    
  55.         this(context, null);    
  56.     }    
  57.         
  58.     public BounceableLinearLayout(Context context, AttributeSet attrs) {    
  59.         super(context, attrs);    
  60.         setClickable(true);    
  61.         setLongClickable(true);    
  62.         mScroller = new Scroller(context);    
  63.         mGestureDetector = new GestureDetector(context, new GestureListenerImpl());    
  64.     }    
  65.     
  66.         
  67.     @Override    
  68.     public void computeScroll() {    
  69.         if (mScroller.computeScrollOffset()) {    
  70.             System.out.println("computeScroll()---> "+  
  71.                                "mScroller.getCurrX()="+mScroller.getCurrX()+","+  
  72.                                "mScroller.getCurrY()="+mScroller.getCurrY());  
  73.             scrollTo(mScroller.getCurrX(), mScroller.getCurrY());    
  74.             //必须执行postInvalidate()从而调用computeScroll()  
  75.             //其实,在此调用invalidate();亦可  
  76.             postInvalidate();   
  77.         }    
  78.         super.computeScroll();    
  79.     }    
  80.         
  81.     @Override    
  82.     public boolean onTouchEvent(MotionEvent event) {    
  83.         switch (event.getAction()) {    
  84.        case MotionEvent.ACTION_UP :    
  85.            //手指抬起时回到最初位置  
  86.            prepareScroll(0, 0);    
  87.             break;    
  88.         default:    
  89.             //其余情况交给GestureDetector手势处理  
  90.             return mGestureDetector.onTouchEvent(event);    
  91.       }    
  92.        return super.onTouchEvent(event);    
  93.    }    
  94.       
  95.     
  96.     class GestureListenerImpl implements GestureDetector.OnGestureListener {  
  97.         @Override  
  98.         public boolean onDown(MotionEvent e) {  
  99.             return true;  
  100.         }  
  101.   
  102.         @Override  
  103.         public void onShowPress(MotionEvent e) {  
  104.   
  105.         }  
  106.   
  107.         @Override  
  108.         public boolean onSingleTapUp(MotionEvent e) {  
  109.             return false;  
  110.         }  
  111.   
  112.         //控制拉动幅度:  
  113.         //int disY=(int)((distanceY - 0.5)/2);  
  114.         //亦可直接调用:  
  115.         //smoothScrollBy(0, (int)distanceY);  
  116.         @Override  
  117.         public boolean onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY) {  
  118.             int disY = (int) ((distanceY - 0.5) / 2);  
  119.             beginScroll(0, disY);  
  120.             return false;  
  121.         }  
  122.   
  123.         public void onLongPress(MotionEvent e) {  
  124.   
  125.         }  
  126.   
  127.         @Override  
  128.         public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) {  
  129.             return false;  
  130.         }  
  131.   
  132.     }    
  133.       
  134.         
  135.     //滚动到目标位置   
  136.     protected void prepareScroll(int fx, int fy) {    
  137.         int dx = fx - mScroller.getFinalX();    
  138.         int dy = fy - mScroller.getFinalY();    
  139.         beginScroll(dx, dy);    
  140.     }    
  141.     
  142.       
  143.      //设置滚动的相对偏移   
  144.     protected void beginScroll(int dx, int dy) {    
  145.         System.out.println("smoothScrollBy()---> dx="+dx+",dy="+dy);  
  146.         //第一,二个参数起始位置;第三,四个滚动的偏移量  
  147.         mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(), dx, dy);    
  148.         System.out.println("smoothScrollBy()---> " +  
  149.                            "mScroller.getFinalX()="+mScroller.getFinalX()+","+  
  150.                            "mScroller.getFinalY()="+mScroller.getFinalY());  
  151.           
  152.         //必须执行invalidate()从而调用computeScroll()  
  153.         invalidate();  
  154.     }   
  155.       
  156.         
  157.       
  158.       
  159. }    
  160.   
  161.    

 

main.xml如下:

 

 

[html] view plain copy
 
 在CODE上查看代码片派生到我的代码片
    1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    2.     xmlns:tools="http://schemas.android.com/tools"  
    3.     android:layout_width="match_parent"  
    4.     android:layout_height="match_parent" >  
    5.   
    6.     <cc.testscroller2.BounceableLinearLayout  
    7.         android:layout_width="match_parent"  
    8.         android:layout_height="match_parent" >  
    9.   
    10.         <TextView  
    11.             android:layout_width="wrap_content"  
    12.             android:layout_height="wrap_content"  
    13.             android:text="向下拉动后松开"   
    14.         />  
    15.           
    16.     </cc.testscroller2.BounceableLinearLayout>  
    17.   
    18. </RelativeLayout>  
posted @ 2016-11-26 15:20  天涯海角路  阅读(60)  评论(0)    收藏  举报