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

MainActivity如下:

package cc.testscroller2;

import android.os.Bundle;
import android.app.Activity;
/**
 * Demo描述:
 * 实现可以拉动后回弹的布局.
 * 类似于下拉刷新的.
 *
 * 参考资料:
 * 1 http://gundumw100.iteye.com/blog/1884373
 * 2 http://blog.csdn.net/gemmem/article/details/7321910
 * 3 http://ipjmc.iteye.com/blog/1615828
 * 4 http://blog.csdn.net/c_weibin/article/details/7438323
 * 5 http://www.cnblogs.com/wanqieddy/archive/2012/05/05/2484534.html
 * 6 http://blog.csdn.net/hudashi/article/details/7353075
 *   Thank you very much
 */
public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
	}

}

BounceableLinearLayout如下:

package cc.testscroller2;
import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.widget.LinearLayout;
import android.widget.Scroller;
/**
 * 总体思路:
 * 处理View的Touch事件,即重写onTouchEvent()方法:
 * 当手指抬起时将其回到原点,其余情况交给GestureDetector处理.
 *
 * 在GestureDetector中重点是覆写onScroll()方法.在该方法中得到
 * Y方向滑动的距离,从而设置 mScroller.startScroll()方法,准备滑动.
 * 随之刷新界面invalidate()从而执行方法computeScroll().
 * 在computeScroll()方法中调用 scrollTo()方法实现真正的滑动.
 *
 * 注意事项:
 * 1 scrollTo()方法的参数:
 *   scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
 *   并且在此之后也要调用postInvalidate()进行刷新
 *
 *
 * 方法说明:
 * 1 mScroller.getFinalX(Y)()
 *   The final X(Y) offset as an absolute distance from the origin.
 *   返回滚动结束位置(得到当前X(Y)距离原始位置的值).仅针对"fling"滚动有效.
 *   也就是说该方法是针对滚动结束而言的.
 *
 *   坐标方向:
 *   X方向的距离,正数向左,负数向右
 *   Y方向的距离,正数向上,负数向下
 *
 * 2 mScroller.getCurrX(Y)()
 *   The new X offset as an absolute distance from the origin.
 *   The new Y offset as an absolute distance from the origin.
 *   返回当前滚动 X(Y)方向的偏移
 *   也就是说该方法是针对滚动中而言的.
 *
 *   坐标方向:
 *   X方向的距离,正数向左,负数向右
 *   Y方向的距离,正数向上,负数向下
 *
 * 3 invalidate()与postInvalidate()的区别
 *   invalidate()在UI线程自身中使用;postInvalidate()在非UI线程中使用.
 *   这是目前网络资料的普遍说法,还待进一步研究.
 *
 * 4 startScroll(int startX, int startY, int dx, int dy, int duration)
 *   第一,二个参数起始位置;第三,四个滚动的偏移量;第五个参数持续时间
 *
 *
 */
public class BounceableLinearLayout extends LinearLayout {
    private Scroller mScroller;
    private GestureDetector mGestureDetector;  

    public BounceableLinearLayout(Context context) {
        this(context, null);
    }  

    public BounceableLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        setClickable(true);
        setLongClickable(true);
        mScroller = new Scroller(context);
        mGestureDetector = new GestureDetector(context, new GestureListenerImpl());
    }  

    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
        	System.out.println("computeScroll()---> "+
        	                   "mScroller.getCurrX()="+mScroller.getCurrX()+","+
        			           "mScroller.getCurrY()="+mScroller.getCurrY());
            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            //必须执行postInvalidate()从而调用computeScroll()
            //其实,在此调用invalidate();亦可
            postInvalidate();
        }
        super.computeScroll();
    }  

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
       case MotionEvent.ACTION_UP :
    	   //手指抬起时回到最初位置
           prepareScroll(0, 0);
            break;
        default:
        	//其余情况交给GestureDetector手势处理
            return mGestureDetector.onTouchEvent(event);
      }
       return super.onTouchEvent(event);
   }  

	class GestureListenerImpl implements GestureDetector.OnGestureListener {
		@Override
		public boolean onDown(MotionEvent e) {
			return true;
		}

		@Override
		public void onShowPress(MotionEvent e) {

		}

		@Override
		public boolean onSingleTapUp(MotionEvent e) {
			return false;
		}

		//控制拉动幅度:
		//int disY=(int)((distanceY - 0.5)/2);
		//亦可直接调用:
		//smoothScrollBy(0, (int)distanceY);
		@Override
		public boolean onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY) {
			int disY = (int) ((distanceY - 0.5) / 2);
			beginScroll(0, disY);
			return false;
		}

		public void onLongPress(MotionEvent e) {

		}

		@Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) {
			return false;
		}

	}  

    //滚动到目标位置
    protected void prepareScroll(int fx, int fy) {
        int dx = fx - mScroller.getFinalX();
        int dy = fy - mScroller.getFinalY();
        beginScroll(dx, dy);
    }  

     //设置滚动的相对偏移
    protected void beginScroll(int dx, int dy) {
    	System.out.println("smoothScrollBy()---> dx="+dx+",dy="+dy);
    	//第一,二个参数起始位置;第三,四个滚动的偏移量
        mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(), dx, dy);
        System.out.println("smoothScrollBy()---> " +
        		           "mScroller.getFinalX()="+mScroller.getFinalX()+","+
        		           "mScroller.getFinalY()="+mScroller.getFinalY());

        //必须执行invalidate()从而调用computeScroll()
        invalidate();
    } 

}

main.xml如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <cc.testscroller2.BounceableLinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="向下拉动后松开"
        />

    </cc.testscroller2.BounceableLinearLayout>

</RelativeLayout>

Android学习Scroller(四)——实现拉动后回弹的布局,布布扣,bubuko.com

时间: 2024-09-29 19:42:58

Android学习Scroller(四)——实现拉动后回弹的布局的相关文章

Android学习Scroller(三)

MainActivity如下: package cc.testscroller2; import android.os.Bundle; import android.app.Activity; /** * Demo描述: * 实现可以拉动后回弹的布局. * 类似于下拉刷新的. * * 参考资料: * 1 http://gundumw100.iteye.com/blog/1884373 * 2 http://blog.csdn.net/gemmem/article/details/7321910

Android学习Scroller(五)——详解Scroller调用过程以及View的重绘

MainActivity如下: package cc.ww; import android.os.Bundle; import android.widget.ImageView; import android.widget.ImageView.ScaleType; import android.widget.RelativeLayout; import android.widget.RelativeLayout.LayoutParams; import android.app.Activity;

Android学习Scroller(三)——控件平移划过屏幕 (Scroller简单使用)

MainActivity如下: package cc.cn; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.app.Activity; /** * Demo描述: * Scroller使用示例--让控件平移划过屏幕 * * 参考资料: * http://blog.cs

Android学习Scroller(一)——View调用scrollTo()的理解及使用

MainActivity如下: package cc.uu; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; import android.app.Activity; /** * Demo描述: * scrollTo()和scrollB

Android学习Scroller(二)

MainActivity如下: package cc.testscroller1; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.os.Bundle; import android.view.View; import android.view.View.OnClick

五、Android学习第四天补充——Android的常用控件(转)

(转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 五.Android学习第四天补充——Android的常用控件 熟悉常用的Android的几个常用控件的使用方法: 一.RadioGroup和RadioButton——单选按钮 二.Checkbox——复选框 三.Toast——提示框,会自动消失 四.ProgressBar——进度条工具 五.ListView——以列表形式将控件显示出来 下面就对这些内容做个详细的解释: 首

四、Android学习第四天——JAVA基础回顾(转)

(转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 四.Android学习第四天——JAVA基础回顾 这才学习Android的第四天,在程序中已经遇到了JAVA中以前不常用的一些知识点,赶紧回顾复习一下,打下基础 这里就做个简单的小结: 一.匿名内部类 匿名内部类说白了就是个没有被命名的JAVA类 在以下条件下使用匿名内部类比较适合: ①只用到该类的一个实例时 ②类在定义后被马上用到 ③类非常小(SUN推荐是在4行代码以下

Android学习Scroller(二)——ViewGroup调用scrollTo()

MainActivity如下: package cc.ac; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.LinearLayout; import android.app.Activity; /** * Demo描述: * 对ViewGroup调用sc

Android学习笔记四:添加Source

问题描述 Source not foundThe JAR file D:\.....\sdk\platforms\android-20\android.jar has no source attachment. 问题原因及解决办法 1. 使用SDK Manager下载最新版本的Sources for Android SDK 一般文件下载目录默认在SDK下的sources文件中即 \adt-bundle-windows-x86_64-20130522\sdk\sources\android-20