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启动从底部向上滑动出现,关闭的时候从顶部向下滑动消失的动画实现---Android提高篇

Activity启动从底部向上滑动出现,关闭的时候从顶部向下滑动消失的动画实现 1.简析实现Activity启动和关闭动画 2.overridePendingTransition()方法简介 3.实现...
  • Sun_2134
  • Sun_2134
  • 2015年11月06日 14:33
  • 4513

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

知识点: 1、需要配置2个动画XML,一个是启动动画,一个是结束动画。 2、启动调用动画的时机和关闭调用动画的时机。 知识点1: 需要在anim下添加两个动画文件:...
  • cc20032706
  • cc20032706
  • 2015年09月09日 17:12
  • 9779

Android下拉上滑显示与隐藏Toolbar另一种实现

关于介绍就不说了,不使用嵌套滑动情况下,另一种实现,当然还可以用design包下的CoordinatorLayout.Behavior。比较简单直接添代码:继承RecyclerView.OnScrol...
  • u010687392
  • u010687392
  • 2015年08月26日 15:25
  • 7025

Android中滑屏实现----手把手教你如何实现触摸滑屏以及Scroller类详解

转载请注明出处:http://blog.csdn.net/qinjuning                 前言:  虽然本文标题的有点标题党的感觉,但无论如何,通过这篇文章的学习以及你...
  • qinjuning
  • qinjuning
  • 2012年04月01日 23:38
  • 71364

Android实现滑动的几种方法

下面通过一个例子来总结实现滑动的几种方式,例子的主要功能就是让我们的自定义View能够随着手指的移动而移动。 布局文件如下: ...
  • shakespeare001
  • shakespeare001
  • 2016年06月13日 15:17
  • 10621

Android 上滑显示底部导航,下滑显示标题bar

本文简单介绍使用属性动画来实现上滑显示底部导航,下滑显示标题bar。先上图看效果,再分析: 可以看出这是个listview有标题和底部,有点像下拉刷新和上拉加载更多。只不过下拉或上拉一定时位置固定...
  • chenshufei2
  • chenshufei2
  • 2015年08月06日 16:02
  • 2298

Android之上下滑动的引导页

无意中看到一篇博文,名字叫
  • gc_gongchao
  • gc_gongchao
  • 2014年09月28日 16:13
  • 4503

Android中滑屏初探 ---- scrollTo 以及 scrollBy方法使用说明

本文原创 ,转载必须注明出处 :http://blog.csdn.net/qinjuning                                             今天给大家介绍下A...
  • qinjuning
  • qinjuning
  • 2012年02月10日 00:02
  • 84057

Android 动画之从上到下,从下往上弹出

从上到下 [html] view plain copy   span style="font-size:18px;">xml version="1...
  • qidabing
  • qidabing
  • 2016年11月29日 19:06
  • 2232

android使用自定义layout实现从下往上的slide效果

  • 2013年06月06日 18:11
  • 686KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android从上往下滑动或从下往上滑动结束Activity
举报原因:
原因补充:

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