1. 程式人生 > >PullScrollView進階(一)----->圖片下拉回彈

PullScrollView進階(一)----->圖片下拉回彈

activity_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"
    tools:context="com.harvic.smoothscrollview.MainActivity" >

    <com.harvic.smoothscrollview.CustomScrollView
        android:layout_width="fill_parent"
        android:layout_height="match_parent">
         <ImageView 
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:scaleType="fitCenter"
                android:src="@drawable/ic_launcher"/>
    </com.harvic.smoothscrollview.CustomScrollView>

</RelativeLayout>

MainActivity
package com.harvic.smoothscrollview;

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {

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

}

CustomScrollView
package com.harvic.smoothscrollview;

import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.TranslateAnimation;
import android.widget.ScrollView;

public class CustomScrollView extends ScrollView {
	// 圖片控制元件檢視
	private View mRootView;
	// 用來儲存手指的當前位置座標值
	private int mpreY = 0;
	// 初始化圖片檢視的矩形區域座標位置
	private Rect mNormalRect;

	public CustomScrollView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	/**
	 * onFinishInflate()函式,明顯是在佈局解析結束後會呼叫的函式。
	 */
	@Override
	protected void onFinishInflate() {
		mRootView = getChildAt(0);
		super.onFinishInflate();
	}

	/**
	 * 在onTouchEvent()中根據手指的移動距離,通過layout()函式將佈局跟隨移動即可
	 */
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// 獲取手指當前的位置y軸座標
		float curY = event.getY();
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN: {
			if (mRootView != null) {
				// 進行佈局位置--獲取圖片初始化的矩形區域
				mNormalRect = new Rect(mRootView.getLeft(), mRootView.getTop(),
						mRootView.getRight(), mRootView.getBottom());
			}
		}
			break;
		case MotionEvent.ACTION_MOVE: {
			// 獲取手指移動的距離--乘以0.25是凸顯阻尼效果
			int delta = (int) ((curY - mpreY) * 0.25);
			if (delta > 0) {
				// 根據手指滑動的距離,進行重新佈局那個圖片View控制元件!!!!!!!!!!!!
				mRootView.layout(mRootView.getLeft(), mRootView.getTop()
						+ delta, mRootView.getRight(), mRootView.getBottom()
						+ delta);
			}
		}
			break;
		case MotionEvent.ACTION_UP: {
			// 獲取手指鬆開的那一刻的圖片的頂部距離
			int curTop = mRootView.getTop();
			// 迴歸到初始化的那個矩形位置即可
			mRootView.layout(mNormalRect.left, mNormalRect.top,
					mNormalRect.right, mNormalRect.bottom);
			TranslateAnimation animation = new TranslateAnimation(0, 0, curTop
					- mNormalRect.top, 0);

			// 下面這樣子也可以
			// mRootView.layout(mRootView.getLeft(), mNormalRect.top,
			// mRootView.getRight(), mNormalRect.bottom);
			// TranslateAnimation animation = new TranslateAnimation(0, 0,
			// curTop
			// - mNormalRect.top, 0);
			animation.setDuration(200);
			mRootView.startAnimation(animation);
		}
			break;
		}
		// 儲存每次手指移動的最新位置
		mpreY = (int) curY;
		return super.onTouchEvent(event);
	}

}

************************************************或者修改自定義ScrollView類,下邊的方式也可以******************************

package com.example.pullscrollview;

import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.TranslateAnimation;
import android.widget.ScrollView;

public class CustomScrollView extends ScrollView {
	// 圖片控制元件檢視
	private View mRootView;
	// 用來儲存手指的當前位置座標值
	private int mpreY = 0;
	// 初始化圖片檢視的矩形區域座標位置
	private Rect mNormalRect;

	public CustomScrollView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	/**
	 * onFinishInflate()函式,明顯是在佈局解析結束後會呼叫的函式。
	 */
	@Override
	protected void onFinishInflate() {
		mRootView = getChildAt(0);
		super.onFinishInflate();
	}

	/**
	 * 在onTouchEvent()中根據手指的移動距離,通過layout()函式將佈局跟隨移動即可
	 */
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// 獲取手指當前的位置y軸座標
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN: {
			mpreY = (int) event.getY();
			if (mRootView != null) {
				// 進行佈局位置--獲取圖片初始化的矩形區域
				mNormalRect = new Rect(mRootView.getLeft(), mRootView.getTop(),
						mRootView.getRight(), mRootView.getBottom());
			}
		}
			break;
		case MotionEvent.ACTION_MOVE: {
			float curY = event.getY();
			// 獲取手指移動的距離--乘以0.25是凸顯阻尼效果
			int delta = (int) (curY - mpreY);
			if (delta > 0) {
				// 根據手指滑動的距離,進行重新佈局那個圖片View控制元件!!!!!!!!!!!!
				mRootView.layout(mRootView.getLeft(), mNormalRect.top
						+ delta, mRootView.getRight(), mNormalRect.bottom
						+ delta);
			}
		}
			break;
		case MotionEvent.ACTION_UP: {
			// 獲取手指鬆開的那一刻的圖片的頂部距離
			int curTop = mRootView.getTop();
			// 迴歸到初始化的那個矩形位置即可
			mRootView.layout(mNormalRect.left, mNormalRect.top,
					mNormalRect.right, mNormalRect.bottom);
			TranslateAnimation animation = new TranslateAnimation(0, 0, curTop
					- mNormalRect.top, 0);

			// 下面這樣子也可以
			// mRootView.layout(mRootView.getLeft(), mNormalRect.top,
			// mRootView.getRight(), mNormalRect.bottom);
			// TranslateAnimation animation = new TranslateAnimation(0, 0,
			// curTop
			// - mNormalRect.top, 0);
			animation.setDuration(200);
			mRootView.startAnimation(animation);
		}
			break;
		}
		// 儲存每次手指移動的最新位置
		return super.onTouchEvent(event);
	}

}