Android 向右滑動銷燬(finish)Activity, 隨着手勢的滑動而滑動並跳轉的效果(二)

寫這篇文章是因爲看了:http://blog.csdn.net/jdsjlzx/article/details/21231217這篇文章,並下載了demo運行了下。

現對其做了一些修改:

(1) 不在通過setTouchView來處理事件,採用事件攔截機制

(2)加入了右側滑動機制

(3)不在對整個activity的觸摸都有效,採用了觸摸點判斷,使其只是左右邊界時纔有效,從而是activity的觸摸事件和listview等控件的滾動相分開

(4)加入左右滑動切換機制的禁用與開啓功能,使其更方便

 

本文只貼上部分代碼,不做原理講述,如果你沒有看上一篇:Android 向右滑動銷燬(finish)Activity, 隨着手勢的滑動而滑動的效果(一),請先看一遍。

demo中使用需要注意的地方,在代碼中都有註釋,有任何問題歡迎聯繫。

 

1、activity佈局,根節點使用定義的view(只對需要滑動的佈局加即可)

<?xml version="1.0" encoding="utf-8"?>
<com.example.view.SildingFinishLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/slidingLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:background="#88ff90" >
        <Button
            android:id="@+id/button1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="單向滑動"
            />
       
    </LinearLayout>

</com.example.view.SildingFinishLayout>

2、SildingFinishLayout的實現

public class SildingFinishLayout extends RelativeLayout{
	private final String TAG = SildingFinishLayout.class.getName();
	
	/**
	 * SildingFinishLayout佈局的父佈局
	 */
	private ViewGroup mParentView;
	
	/**
	 * 滑動的最小距離
	 */
	private int mTouchSlop;
	/**
	 * 按下點的X座標
	 */
	private int downX;
	/**
	 * 按下點的Y座標
	 */
	private int downY;
	/**
	 * 臨時存儲X座標
	 */
	private int tempX;
	/**
	 * 滑動類
	 */
	private Scroller mScroller;
	/**
	 * SildingFinishLayout的寬度
	 */
	private int viewWidth;
	/**
	 * 記錄是否正在滑動
	 */
	private boolean isSilding;
	
	private OnSildingFinishListener onSildingFinishListener;
	
	private boolean enableLeftSildeEvent = true; //是否開啓左側切換事件
	private boolean enableRightSildeEvent = true; // 是否開啓右側切換事件
	private final int size = 20; //按下時範圍(處於這個範圍內就啓用切換事件,目的是使當用戶從左右邊界點擊時才響應)
	private boolean isIntercept = false; //是否攔截觸摸事件
	private boolean canSwitch;//是否可切換
	private boolean isSwitchFromLeft = false; //左側切換
	private boolean isSwitchFromRight = false; //右側側切換
	

	public SildingFinishLayout(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public SildingFinishLayout(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);

		mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
		Log.e(TAG, "設備的最小滑動距離:" + mTouchSlop);
		mScroller = new Scroller(context);
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		super.onLayout(changed, l, t, r, b);
		if (changed) {
			// 獲取SildingFinishLayout所在佈局的父佈局
			mParentView = (ViewGroup) this.getParent();
			viewWidth = this.getWidth();
		}
		Log.e(TAG, "viewWidth=" + viewWidth);
	}
	
	
	public void setEnableLeftSildeEvent(boolean enableLeftSildeEvent) {
		this.enableLeftSildeEvent = enableLeftSildeEvent;
	}
	
	
	public void setEnableRightSildeEvent(boolean enableRightSildeEvent) {
		this.enableRightSildeEvent = enableRightSildeEvent;
	}
	

	/**
	 * 設置OnSildingFinishListener, 在onSildingFinish()方法中finish Activity
	 * 
	 * @param onSildingFinishListener
	 */
	public void setOnSildingFinishListener(
			OnSildingFinishListener onSildingFinishListener) {
		this.onSildingFinishListener = onSildingFinishListener;
	}
	
	//是否攔截事件,如果不攔截事件,對於有滾動的控件的界面將出現問題(相沖突)
	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		float downX = ev.getRawX();
		Log.e(TAG, "downX =" + downX + ",viewWidth=" + viewWidth);
		if(enableLeftSildeEvent && downX < size){
			Log.e(TAG, "downX 在左側範圍內 ,攔截事件");
			isIntercept = true;
			isSwitchFromLeft = true;
			isSwitchFromRight = false;
			return true;
		}else if(enableRightSildeEvent && downX > (viewWidth - size)){
			Log.e(TAG, "downX 在右側範圍內 ,攔截事件");
			isIntercept = true;
			isSwitchFromRight = true;
			isSwitchFromLeft = false;
			return true;
		}else{
			Log.e(TAG, "downX 不在範圍內 ,不攔截事件");
			isIntercept = false;
			isSwitchFromLeft = false;
			isSwitchFromRight = false;
		}
		return super.onInterceptTouchEvent(ev);
	}


	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if(!isIntercept){//不攔截事件時 不處理
			return false;
		}
		switch (event.getAction()){
		case MotionEvent.ACTION_DOWN:
			downX = tempX = (int) event.getRawX();
			downY = (int) event.getRawY();
			break;
		case MotionEvent.ACTION_MOVE:
			int moveX = (int) event.getRawX();
			int deltaX = tempX - moveX;	
			tempX = moveX;
			if (Math.abs(moveX - downX) > mTouchSlop && Math.abs((int) event.getRawY() - downY) < mTouchSlop) {
				isSilding = true;
			}
			
			Log.e(TAG, "scroll deltaX=" + deltaX);			
			if(enableLeftSildeEvent){//左側滑動
				if (moveX - downX >= 0 && isSilding) {
					mParentView.scrollBy(deltaX, 0);
				}
			}
			
			if(enableRightSildeEvent){//右側滑動
				if (moveX - downX <= 0 && isSilding) {
					mParentView.scrollBy(deltaX, 0);
				}
			}
			
			Log.e(TAG + "/onTouchEvent", "mParentView.getScrollX()=" + mParentView.getScrollX());
			break;
		case MotionEvent.ACTION_UP:
			isSilding = false;
			//mParentView.getScrollX() <= -viewWidth / 2  ==>指左側滑動
			//mParentView.getScrollX() >= viewWidth / 2   ==>指右側滑動
			if (mParentView.getScrollX() <= -viewWidth / 2 || mParentView.getScrollX() >= viewWidth / 2) {
				canSwitch = true;
				if(isSwitchFromLeft){
					scrollToRight();
				}
				
				if(isSwitchFromRight){
					scrollToLeft();
				}
			} else {
				scrollOrigin();
				canSwitch = false;
			}
			break;
		}
		return true;
	}
	
	
	/**
	 * 滾動出界面至右側
	 */
	private void scrollToRight() {
		final int delta = (viewWidth + mParentView.getScrollX());
		// 調用startScroll方法來設置一些滾動的參數,我們在computeScroll()方法中調用scrollTo來滾動item
		mScroller.startScroll(mParentView.getScrollX(), 0, -delta + 1, 0, Math.abs(delta));
		postInvalidate();
	}
	
	/**
	 * 滾動出界面至左側
	 */
	private void scrollToLeft() {
		final int delta = (viewWidth - mParentView.getScrollX());
		// 調用startScroll方法來設置一些滾動的參數,我們在computeScroll()方法中調用scrollTo來滾動item
		mScroller.startScroll(mParentView.getScrollX(), 0, delta - 1, 0, Math.abs(delta));//此處就不可用+1,也不卡直接用delta
		postInvalidate();
	}

	/**
	 * 滾動到起始位置
	 */
	private void scrollOrigin() {
		int delta = mParentView.getScrollX();
		mScroller.startScroll(mParentView.getScrollX(), 0, -delta, 0,
				Math.abs(delta));
		postInvalidate();
	}
	
	

	@Override
	public void computeScroll(){
		// 調用startScroll的時候scroller.computeScrollOffset()返回true,
		if (mScroller.computeScrollOffset()) {
			mParentView.scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
			postInvalidate();

			if (mScroller.isFinished()) {
				if (onSildingFinishListener != null && canSwitch) {
					Log.e(TAG, "mScroller finish");
					if(isSwitchFromLeft){//回調,左側切換事件
						onSildingFinishListener.onSildingBack();
					}
					
					if(isSwitchFromRight){//右側切換事件
						onSildingFinishListener.onSildingForward();
					}
				}
			}
		}
	}
	

	public interface OnSildingFinishListener {
		public void onSildingBack();
		public void onSildingForward();
	}

}


3、BaseActivity

/**
 * 1. 必須設置透明風格,設置透明後需對Activity設置一個背景色,其遮蓋效果
 * 2. 要調用initBaseActivity(boolean enableLeftSilde, boolean enableRigftSilde)
 * 
 * @ enableLeftSilde : 開啓左側
 * @ enableRightSilde : 開啓右側
 * 
 * */
public class BaseActivity extends Activity implements OnSildingFinishListener{
	private SildingFinishLayout sildingLayout;
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
	}
	
	/**
	 * @enableLeftSilde : 開啓左側
 	 * @enableRightSilde : 開啓右側
 	 * */
	public void initBaseActivity(boolean enableLeftSilde, boolean enableRigftSilde){
		sildingLayout = (SildingFinishLayout) findViewById(R.id.slidingLayout);
		sildingLayout.setOnSildingFinishListener(this);
		sildingLayout.setEnableLeftSildeEvent(enableLeftSilde);
		sildingLayout.setEnableRightSildeEvent(enableRigftSilde);
	}


	@Override
	public void onSildingBack() {
		Toast.makeText(getApplicationContext(), "back", Toast.LENGTH_SHORT).show();
		finish();
	}


	@Override
	public void onSildingForward() {
		Toast.makeText(getApplicationContext(), "前進", Toast.LENGTH_SHORT).show();
		finish();
	}
}

 

歡迎有需要的朋友下載,0積分,有問題相互交流。

下載地址:  Activity滑動跳轉

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章