欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android仿iOS侧滑退出当前界面功能

程序员文章站 2022-03-08 13:03:27
我们都知道在ios手机上面,有一个侧滑退出当前界面的功能,但是在安卓手机上系统没有给我们提供这样的功能,但是这依然阻挡不了强大的安卓的定制功能,我们完全可以自己定制一套这样...

我们都知道在ios手机上面,有一个侧滑退出当前界面的功能,但是在安卓手机上系统没有给我们提供这样的功能,但是这依然阻挡不了强大的安卓的定制功能,我们完全可以自己定制一套这样的功能。

首先看下效果图:

Android仿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侧滑退出当前界面功能

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。