一行代码实现Android右滑返回

一行代码实现Android右滑返回

    • 一、使用方式Usage
    • 二、代码解析
    • 三、设计思路
    • 四、方案过滤
    • 五、实现过程
        • 1、实现NavigationLayout
        • 2、添加NavigationLayout
        • 3、获取上一个Activity
    • 六、参考项目

一、使用方式Usage

  • 实现效果

演示工程项目

点击下载演示APK

  • 导入and next_navigation模块

下载地址:https://github.com/jicanghai37927/WhatsAndroid/tree/master/andnext_navigation

  • 在Application的onCreate()方法中调用
NavigationHelper.onCreate()

所有的Activity支持右滑返回。

  • 在Activity的onCreate()方法中调用
NavigationHelper.onCreate(); // 必须在调用super.onCreate()方法之前
super.onCreate(); 

之后所有的Activity都会支持右滑返回。

  • 关闭Activity的右滑返回
NavigationHelper.exclude(this); // 必须在调用super.onCreate()方法之前
super.onCreate(); 

调用NavigationHelper.exclude()之后,该Activity即不再支持右滑返回。

二、代码解析

  • 代码结构
package club.andnext.navigation;
	NavigationHelper.java // 管理NavigationLayout
	NavigationLayout.java // 负责用户交互,实现右滑效果
  • NavigationLayout.java

NavigationLayout负责实现右滑效果,关键代码是使用ViewDragHelper实现拖拽效果。

  • NavigationHelper.java

NavigationHelper实现了Application.ActivityLifecycleCallbacks接口,监听Activity事件。

在onCreate()事件中,创建并添加NavigationLayout到DecorView中。

在onStop()事件中,为NavigationLayout设置上一个Activity的DecorView截图,从而实现右滑显示上一个Activity内容。

三、设计思路

  • 首先,如何处理用户的触摸事件来判断用户滑动?

2个地方可以处理触摸事件,ActivityViewdispatchTouchEvent()方法。

如果采用Activity的方式,则定义一个基类NavigationActivity来处理用户触摸事件,并且要求所有支持右滑返回的Activity均继承自NavigationActivity。

如果采用View的方式,则定义控件NavigationLayout,并将NavigationLayout加入到Activity的控件结构中。

  • 其次,如何将View插入到Activity的控件结构中?

1、通过setContentView()将NavigationLayout加入到控件结构中;

2、通过ActivitygetWindow().getDecorView()获取根控件,并添加NavigationLayout;

  • 第三,如何显示上一个Activity的内容?

2种方法可以显示上一个Activity的内容。

1、将当前Activity的主题设置为透明,即false

2、获取当前Activity的控件结构,即this.getWindow().getDecorView()

如果采用的是第2种方式,我们还需要获取到上一个Activity实例。

  • 第四,如何获取到上一个Activity实例?

ApplicationActivityLifecycleCallbacks可以帮助我们实现这个功能。

处理完这3个问题,我们可以展示当前及上一个Activity的内容,并且也可以处理触摸事件来实现滑动功能。如何将这些功能串联到一起?

四、方案过滤

  • 第一、采用ViewdispatchTouchEvent()方式来处理触摸事件。

Activity方式要求所有支持右滑返回的Activity都必须继承自基类NavigationActivity,侵入性太强,并且可能遇到无法继承的情况。

  • 第二、采用this.getWindow().getDecorView()方式来显示上一个Activity内容。

透明主题方式要求每个支持右滑返回的Activity的主题都必须是透明的,侵入性太强,不适合应用于应用内的所有Activity,局部使用可以考虑。

五、实现过程

第一、实现NavigationLayout处理触摸事件并展示Activity内容。

第二、将NavigationLayout添加到Activity的控件结构中。

第三、为NavigationLayout提供上一个Activity的内容。

第四、NavigationLayout右滑结束,关闭当前Activity。

1、实现NavigationLayout

2、添加NavigationLayout

比较ActivityFragmentActivityAppCompatActivity三种Activity的控件结构

onCreate()setContentView()后的控件结构

com.android.internal.policy.DecorView[-1][子控件数 = 1]
android.widget.LinearLayout[-1][子控件数 = 2]
android.widget.FrameLayout[16908290][子控件数 = 1]

设置的ContentView = android.widget.LinearLayout
com.android.internal.policy.DecorView[-1][子控件数 = 1]
android.widget.LinearLayout[-1][子控件数 = 2]
android.widget.FrameLayout[16908290][子控件数 = 1]

设置的ContentView = android.widget.LinearLayout
com.android.internal.policy.DecorView[-1][子控件数 = 1]
android.widget.LinearLayout[-1][子控件数 = 2]
android.widget.FrameLayout[-1][子控件数 = 1]
androidx.appcompat.widget.ActionBarOverlayLayout[2131230791][子控件数 = 2]
androidx.appcompat.widget.ContentFrameLayout[16908290][子控件数 = 1]

设置的ContentView = android.widget.LinearLayout

onStop()之后的控件结构

android.view.ViewRootImpl
com.android.internal.policy.DecorView[-1][子控件数 = 3]
android.widget.LinearLayout[-1][子控件数 = 2]
android.widget.FrameLayout[16908290][子控件数 = 1]

设置的ContentView = android.widget.LinearLayout
android.view.ViewRootImpl
com.android.internal.policy.DecorView[-1][子控件数 = 3]
android.widget.LinearLayout[-1][子控件数 = 2]
android.widget.FrameLayout[16908290][子控件数 = 1]

设置的ContentView = android.widget.LinearLayout
android.view.ViewRootImpl
com.android.internal.policy.DecorView[-1][子控件数 = 3]
android.widget.LinearLayout[-1][子控件数 = 2]
android.widget.FrameLayout[-1][子控件数 = 1]
androidx.appcompat.widget.ActionBarOverlayLayout[2131230791][子控件数 = 2]
androidx.appcompat.widget.ContentFrameLayout[16908290][子控件数 = 1]

设置的ContentView = android.widget.LinearLayout

结论:将NavigationLayout添加到DecorView,并且将DecorView的子控件移动到Navigation中。

3、获取上一个Activity

六、参考项目

  • SwipeBackHelper:https://github.com/Jude95/SwipeBackHelper

  • SwipeBackLayout:https://github.com/ikew0ng/SwipeBackLayout

  • and_swipeback:https://github.com/XBeats/and_swipeback

你可能感兴趣的:(安卓实战手册)