Android从上往下滑动或从下往上滑动结束Activity

原创 2016年08月29日 15:11:22

之前有看过xiaanming写的侧滑返回,于是仿照他的Demo,写了这个从上往下滑动或者从下往上滑动结束Activity


先附图一张,由于这台电脑分辨率有问题以及模拟器的缘故,先凑活看吧




先贴代码:

从上往下滑动:


import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.Scroller;

/***
 * 
 * 从上向下滑结束Activity
 * 
 * @author 帽檐遮不住阳光
 * 
 */
public class TopToBottomFinishLayout extends RelativeLayout {
	
	/**
	 * TopToBottomFinishLayout布局的父布局
	 */
	private ViewGroup mParentView;
	/**
	 * 滑动的最小距离
	 */
	private int mTouchSlop;
	/**
	 * 按下点的X坐标
	 */
	private int downX;
	/**
	 * 按下点的Y坐标
	 */
	private int downY;
	/**
	 * 临时存储X坐标
	 */
	private int tempY;
	/**
	 * 滑动类
	 */
	private Scroller mScroller;
	/**
	 * TopToBottomFinishLayout的宽度
	 */
	private int viewHeight;

	private boolean isSilding;

	private OnFinishListener onFinishListener;
	private boolean isFinish;

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

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

		mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
		mScroller = new Scroller(context);
	}

	/**
	 * 事件拦截操作
	 */
	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {

		switch (ev.getAction()) {
		case MotionEvent.ACTION_DOWN:
			downX = (int) ev.getRawX();
			downY = tempY = (int) ev.getRawY();
			break;
		case MotionEvent.ACTION_MOVE:
			int moveY = (int) ev.getRawY();
			// 满足此条件屏蔽SildingFinishLayout里面子类的touch事件
			if (Math.abs(moveY - downY) > mTouchSlop
					&& Math.abs((int) ev.getRawX() - downX) < mTouchSlop) {
				return true;
			}
			break;
		}
		return super.onInterceptTouchEvent(ev);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_MOVE:
			int moveY = (int) event.getRawY();// 触摸点相对于屏幕的位置
			int deltaY = tempY - moveY;
			tempY = moveY;
			if (Math.abs(moveY - downY) > mTouchSlop
					&& Math.abs((int) event.getRawX() - downX) < mTouchSlop) {
				isSilding = true;
			}

			if (moveY - downY >= 0 && isSilding) {
				mParentView.scrollBy(0, deltaY);
			}
			break;
		case MotionEvent.ACTION_UP:
			isSilding = false;
			if (mParentView.getScrollY() <= -viewHeight / 3) {
				isFinish = true;
				scrollBottom();
			} else {
				scrollOrigin();
				isFinish = false;
			}
			break;
		}

		return true;
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		super.onLayout(changed, l, t, r, b);
		if (changed) {
			mParentView = (ViewGroup) this.getParent();
			viewHeight = this.getHeight();
		}
	}

	/***
	 * 接口回调
	 */
	public void setOnFinishListener(
			OnFinishListener onSildingFinishListener) {
		this.onFinishListener = onSildingFinishListener;
	}

	/**
	 * 滚动出界面
	 */
	private void scrollBottom() {
		final int delta = (viewHeight + mParentView.getScrollY());
		mScroller.startScroll(0, mParentView.getScrollY(), 0, -delta + 1,
				Math.abs(delta));
		postInvalidate();
	}

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

	@Override
	public void computeScroll() {
		if (mScroller.computeScrollOffset()) {
			mParentView.scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
			postInvalidate();

			if (mScroller.isFinished() && isFinish) {
				if (onFinishListener != null) {
					onFinishListener.onFinish();
				} else {
					// 没有设置OnSildingFinishListener,让其滚动到其实位置
					scrollOrigin();
					isFinish = false;
				}
			}
		}
	}

	public interface OnFinishListener {
		public void onFinish();
	}

}


从下往上滑动:


import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.Scroller;

/***
 * 
 * 从下向上滑结束Activity
 * 
 * @author 帽檐遮不住阳光
 * 
 */
public class BottomToTopFinishLayout extends RelativeLayout {
	
	/**
	 * BottomFinishLayout布局的父布局
	 */
	private ViewGroup mParentView;
	/**
	 * 滑动的最小距离
	 */
	private int mTouchSlop;
	/**
	 * 按下点的X坐标
	 */
	private int downX;
	/**
	 * 按下点的Y坐标
	 */
	private int downY;
	/**
	 * 临时存储X坐标
	 */
	private int tempY;
	/**
	 * 滑动类
	 */
	private Scroller mScroller;
	/**
	 * BottomFinishLayout的宽度
	 */
	private int viewHeight;

	private boolean isSilding;

	private OnFinishListener onFinishListener;
	private boolean isFinish;

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

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

		mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
		mScroller = new Scroller(context);
	}

	/**
	 * 事件拦截操作
	 */
	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {

		switch (ev.getAction()) {
		case MotionEvent.ACTION_DOWN:
			downX = (int) ev.getRawX();
			downY = tempY = (int) ev.getRawY();
			break;
		case MotionEvent.ACTION_MOVE:
			int moveY = (int) ev.getRawY();
			// 满足此条件屏蔽SildingFinishLayout里面子类的touch事件
			if (Math.abs(downY - moveY) > mTouchSlop
					&& Math.abs((int) ev.getRawX() - downX) < mTouchSlop) {
				return true;
			}
			break;
		}
		return super.onInterceptTouchEvent(ev);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_MOVE:
			int moveY = (int) event.getRawY();// 触摸点相对于屏幕的位置
			int deltaY = moveY - tempY;
			tempY = moveY;
			if (Math.abs(downY - moveY) > mTouchSlop
					&& Math.abs((int) event.getRawX() - downX) < mTouchSlop) {
				isSilding = true;
			}

			if (downY - moveY >= 0 && isSilding) {
				mParentView.scrollBy(0, -deltaY);
			}
			break;
		case MotionEvent.ACTION_UP:
			isSilding = false;
			System.out.println("vvv===========" + mParentView.getScrollY());
			System.out.println("/3============" + viewHeight / 3);
			if (mParentView.getScrollY() >= viewHeight / 3) {
				isFinish = true;
				scrollTop();
			} else {
				scrollOrigin();
				isFinish = false;
			}
			break;
		}
		return true;
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		super.onLayout(changed, l, t, r, b);
		if (changed) {
			mParentView = (ViewGroup) this.getParent();
			viewHeight = this.getHeight();
		}
	}

	/***
	 * 接口回调
	 */
	public void setOnFinishListener(OnFinishListener onSildingFinishListener) {
		this.onFinishListener = onSildingFinishListener;
	}

	/**
	 * 滚动出界面
	 */
	private void scrollTop() {
		final int delta = (viewHeight - mParentView.getScrollY());
		mScroller.startScroll(0, mParentView.getScrollY(), 0, delta - 1,
				Math.abs(delta));
		postInvalidate();
	}

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

	@Override
	public void computeScroll() {
		if (mScroller.computeScrollOffset()) {
			mParentView.scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
			postInvalidate();
			if (mScroller.isFinished() && isFinish) {
				if (onFinishListener != null) {
					onFinishListener.onFinish();
				} else {
					// 没有设置OnSildingFinishListener,让其滚动到其实位置
					scrollOrigin();
					isFinish = false;
				}
			}
		}
	}

	public interface OnFinishListener {
		public void onFinish();
	}

}


Activity:

 public class FromTopActivity extends Activity {


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_from_top);
TopToBottomFinishLayout bottomFinishLayout = (TopToBottomFinishLayout) findViewById(R.id.layout);
bottomFinishLayout.setOnFinishListener(new OnFinishListener() {


@Override
public void onFinish() {
finish();
}
});
}


}

layout:

<?xml version="1.0" encoding="utf-8"?>
<com.example.mytest.TopToBottomFinishLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#5DC890"
    android:orientation="vertical" >

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="TestActivity"
        android:textColor="#ff8840" />

</com.example.mytest.TopToBottomFinishLayout>



要实现其实很简单,在onTouchEvent里判断手指移动的距离,如果大于自己设定的临界值,则滚动到顶部或者底部,否则回到初始位置。所以这里用到了Scroller,scroller.startScroll后,postInvalidate刷新界面。

最后重写computeScroll,在computeScroll里判断Scroller是否已经finish以及手指移动的距离是否大于自己设定的临界值。


最后一定要记得,在AndroidManifest.xml里要将Activity的Theme设置为Theme.Translucent,否则看不到效果


Demo:http://download.csdn.net/detail/qq_18612815/9615890



仿微信:Activity跟随手指滑动效果SlideFinishActivity

概述让Activity跟随者手指的滑动而滑动,当向右滑动到一定距离或者往右滑动到达一定速度就finish,类似于微信滑动finish的效果。 1、支持边界滑动和全屏滑动两种模式 2、解决了滑动冲突问...

Android 向右滑动销毁(finish)Activity, 随着手势的滑动而滑动的效果

今天给大家带来一个向右滑动切换Activity的效果,Activtiy随着手指的移动而移动,该效果在Android应用中还是比较少见的,在IOS中就比较常见了,例如“网易新闻” ,"美食杰" , "淘...

activity动画,从下往上进入,从上往下关闭

知识点: 1、需要配置2个动画XML,一个是启动动画,一个是结束动画。 2、启动调用动画的时机和关闭调用动画的时机。 知识点1: 需要在anim下添加两个动画文件:...

android窗体动画:activity启动从底部向上滑动出现,关闭的时候从顶部向下滑动消失的动画实现

在IOS系统里,我们打开app都是有启动动画的,这样子在打开一个新窗体,用户感觉有个过渡动画,体验效果很好,不会觉得很突然就冒出一个窗体,下面就实现一个android 的activity启动和关闭动画...

activity跳转时从上到下,退出时从下到上

需求:A activity 点击控件跳转B  activity时B要从上到下出来,B 退出时从下到上消失...
  • oAiTan
  • oAiTan
  • 2016年01月06日 16:27
  • 1603

Activity从底部向上半透明弹出效果实现

Activity从底部向上半透明弹出效果实现

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

滑动切换Activity

百度贴吧有滑动切换Activity的功能,感觉很方便: 这种功能要自己写还是挺复杂的,幸运的是,已经有比较成熟的开源项目,项目地址:https://github.com/r0adkll/Slid...

实现View的 上下滑动1--简单实现

上拉与下拉简单实现 -- 记录点1
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android从上往下滑动或从下往上滑动结束Activity
举报原因:
原因补充:

(最多只允许输入30个字)