Android仿iOS侧滑退出当前界面功能
我们都知道在ios手机上面,有一个侧滑退出当前界面的功能,但是在安卓手机上系统没有给我们提供这样的功能,但是这依然阻挡不了强大的安卓的定制功能,我们完全可以自己定制一套这样的功能。
首先看下效果图:
分析:
(1)要想模仿ios的这种效果,因为我们通过手指的滑动,所以这里肯定跟我们的滑动事件有关系(onintercepttouchevent,ontouchevent这两个方法的关系,如果不清楚,请直接查阅事件传递机制原理)
(2)我们要想直接拦截我们的所有触摸事件,我们可以在上层父级布局中进行拦截和处理,这里我们想到了decorview。首先我们应该知道activity的*父view是decorview,获取我们的decorview也很简单
getwindow().getdecorview()
我们平时写的那些xml布局文件都是包裹在这个decorview中的,所以这里我们就有了一个思路:
我们可以在我们的xml布局和decorview中间添加一个中间布局(slidinglayout),然后所有的滑动逻辑和滑动冲突全部在这里面处理。
(3)比较关键的是:当我们需要使用侧滑动能的activity我们需要将它的主题设置成透明,这样滑动的时候就不会遮挡下面的activity,代码如下:
<style name="apptheme.slide" parent="@style/apptheme"> <!--required--> <item name="android:windowbackground">@android:color/transparent</item> <item name="android:windowistranslucent">true</item> <item name="android:windowanimationstyle">@style/apptheme.slide.animation</item> </style>
(4)当我们滑动超过半屏的时候,退出当前界面,否则则回退到原始位置。这里使用scroller
下面直接上代码进行分析:
1)、触摸事件的处理过程,按下的位置大于x轴的十分之一就拦截当前事件,交给slidinglayout的ontouchevent处理
/** * 根据手指移动的距离判断是否拦截触摸事件 * * @param ev * @return */ @override public boolean onintercepttouchevent(motionevent ev) { int x = (int) ev.getx(); int y = (int) ev.gety(); boolean mintercept = false; switch (ev.getaction()) { case motionevent.action_down: minterceptdownx = x; mlastinterceptx = x; mlastintercepty = y; break; case motionevent.action_move: int movex = x - mlastinterceptx; int movey = y - mlastintercepty; //按下的位置的x位置小于屏幕的十分之一,并且x移动的距离大于y移动的距离,就拦截 if (minterceptdownx < (getwidth() / 10) && math.abs(movex) > math.abs(movey)) { mintercept = true; } else { mintercept = false; } mlastinterceptx = x; mlastintercepty = y; break; case motionevent.action_up: //抬起的时候重置参数 mintercept = false; minterceptdownx = mlastinterceptx = mlastintercepty = 0; break; } return mintercept; } private int mtouchdownx; private int mlasttouchx; private int mlasttouchy; @override public boolean ontouchevent(motionevent event) { boolean mconsumed = false; int x = (int) event.getx(); int y = (int) event.gety(); switch (event.getaction()) { case motionevent.action_down: mtouchdownx = x; mlasttouchx = x; mlasttouchy = y; break; case motionevent.action_move: int movex = x - mlasttouchx; int movey = y - mlasttouchy; if (mtouchdownx < (getwidth() / 10) && math.abs(movex) > math.abs(movey) && !mconsumed) { mconsumed = true; } if (mconsumed) { int rightmovex = (int) (mlasttouchx - event.getx()); if ((getscrollx() + rightmovex) > 0) { //向左滑动的时候,getscrollx()和rightmovex都大于0,所以禁止滑动 scrollto(0, 0); } else { scrollby(rightmovex, 0); } } mlasttouchx = x; mlasttouchy = y; break; case motionevent.action_up: mconsumed = false; mtouchdownx = mlasttouchx = mlasttouchy = 0; if(-getscrollx()<getwidth()/2){ //偏移量不到屏幕宽度的一般,就回到最初的位置 scrollback(); }else{ scrollfinish(); } break; case motionevent.action_cancel: mconsumed = false; mtouchdownx = mlasttouchx = mlasttouchy = 0; if(-getscrollx()<getwidth()/2){ //偏移量不到屏幕宽度的一般,就回到最初的位置 scrollback(); }else{ scrollfinish(); } break; } return true; }
2)、滑动的偏移量超出屏幕的一办,就关闭当前界面否则回到初始位置
/** * 滑动到最初的位置 */ private void scrollback() { int startx = getscrollx(); int dx = -getscrollx(); mscroller.startscroll(startx, 0, dx, 0, 300); invalidate(); } /** * 向右滑动关闭 */ private void scrollfinish(){ int dx = -getscrollx() - getwidth(); mscroller.startscroll(getscrollx(),0,dx,0,300); invalidate(); }
3)、我们可以将这些侧滑处理放在我们的baseactivity当中,需要侧滑的activity只要继承这个baseactivity并且主题设置成透明就可以了
@override protected void oncreate(@nullable bundle savedinstancestate) { super.oncreate(savedinstancestate); if(enablerightsliding()){ slidinglayout slidinglayout = new slidinglayout(this); slidinglayout.replacecurrentlayout(this); } } /** * 子类重写这个方法true:允许向右滑动,false:禁止向右滑动 * @return */ protected boolean enablerightsliding(){ return false; }
源码下载:仿ios侧滑退出当前界面功能
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。