and_swipeback

Project Url: XBeats/and_swipeback
Introduction: 高仿最新版微信 6.2 手势滑动返回
More: Author   ReportBugs   
Tags:
滑动返回-微信右滑返回-

利用滑动手势退出当前 Activity

License maven--central

Features

  • 不需要设置透明 theme 或windowIsTranslucent = true
  • 不影响 activity 的生命周期
  • 只需继承 SwipeBackActivity
  • 支持 Dialog 的滑动返回

Getting started

Firstly,add the following lines to your app/build.gradle.

dependencies {  
    compile 'com.aitangba:swipeback:1.0.3'
}

Secondly, add the following lines to your application.

public class CustomApplication extends Application{

    @Override
    public void onCreate() {
        super.onCreate();
        registerActivityLifecycleCallbacks(ActivityLifecycleHelper.build());
    }

}

Finally, set the activity which need to swipe extends the SwipeBackActivity.

public class BaseActivity extends SwipeBackActivity {

}

Usage

API

Application 在 Api14 之后添加了新的 Callback 方法

    public void registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) {

    }

这样就可以根据 activity 的生命周期缓存所有 Activity,通过 list 获取上一个 activity 的实例,从而获取 id 为 content 的 ContentView 的子 View(即 setContentView 中的 View),并进行滑动展示。

默认 SwipeBackActivity 是支持滑动返回的,不需要滑动返回时则需要复写 SwipeBackActivity 的方法supportSlideBack,其中方法canBeSlideBack意思是能否返回至本 Activity;两个方法相互配合使用,以应对各种需求。


   public class SwipeBackActivity extends AppCompatActivity implements SwipeBackHelper.SlideBackManager {

    private SwipeBackHelper mSwipeBackHelper;

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (!supportSlideBack()) {
            return super.dispatchTouchEvent(ev);
        }
        if (mSwipeBackHelper == null) {
            mSwipeBackHelper = new SwipeBackHelper(this, new SlideActivityAdapter());
            // 滑动返回触发 finish
            mSwipeBackHelper.setOnSlideFinishListener(new SwipeBackHelper.OnSlideFinishListener() {
                @Override
                public void onFinish() {
                    SwipeBackActivity.this.finish();
                    overridePendingTransition(android.R.anim.fade_in, R.anim.hold_on);
                }
            });
        }
        return mSwipeBackHelper.processTouchEvent(ev) || super.dispatchTouchEvent(ev);
    }

    @Override
    public void finish() {
        if (mSwipeBackHelper != null) {
            mSwipeBackHelper.finishSwipeImmediately();
        }
        super.finish();
    }

    @Override
    public boolean supportSlideBack() {
        return true;
    }

    @Override
    public boolean canBeSlideBack() {
        return true;
    }

    // 独立获取上一个 Activity
    private static class SlideActivityAdapter implements SlideActivityCallback {

        @Override
        public Activity getPreviousActivity() {
            return ActivityLifecycleHelper.getPreviousActivity();
        }
    }
}

6 种事件状态


    private static final int STATE_ACTION_DOWN = 1; //点击事件
    private static final int STATE_ACTION_UP = 2;  //点击结束
    private static final int STATE_BACK_START = 3; //开始滑动,不返回前一个页面
    private static final int STATE_BACK_FINISH = 4;  //结束滑动,不返回前一个页面
    private static final int STATE_FORWARD_START = 5; //开始滑动,返回前一个页面
    private static final int STATE_FORWARD_FINISH = 6;//结束滑动,返回前一个页面
  1. 在 Down 手势发生时,只要将上一个 Activity 的 ContentView 从 parentView 中剥离,并加入到当前 View 的 ContentView 中;
  2. 在滑动手势发生时,加上阴影 View,并进行滑动;同时滑动的有当前 Activity 的 ContentView、上一个 Activity 的 ContentView 和自定义的阴影 View;
  3. 在 Up 手势发生时,判断滑动是否超过屏幕 1/4,触发返回操作,并展示滑动动画;
  4. 滑动取消或滑动返回发生时,需要将上个 Activity 的 ContentView 从新加入到上一个 Acitivity 的布局中。

Tips:
在设计过程中遇到也有过其他思路:
1)设置 Activity 的透明 theme,可是发现只要 activity 的层级变多就会变得非常卡顿;
2)动态设置 Activity 的 theme,这需要通过反射,而且还需要判断 api,部分手机还不兼容;
3)在滑动展示上个 Activity 的 View 时,直接将上个 Activity 的 contentView 截图保存在内存卡上,然后显示在当前 Activity 的 view 上,但是有明显的卡顿感;
以上都是在设计过程中想到的方案,也逐个实践了一下,发现问题还是比较多的,想想还不如另辟蹊径,就有了现在的方案,目前看来还是能兼容大部分手机的。

ScreenShot

image

Update

  • 1.0.1
    添加接口 SlideBackManager;
    修正手势判断,仅在可滑动区域进行滑动手势判断,不干扰点击或长按事件;
    修复由于其他多线程在滑动页面进行中时,调用 finish 方法导致异常发生的问题
  • 1.0.2
    优化库中类的结构;
    为兼容高德地图的滑动事件,在触发滑动事件时,通知底层 View 的取消当前的点击或滑动事件;

  • 1.0.3
    SwipeBackHelper 去除继承 hanhler;
    优化 SwipeBackHelper 代码结构,将涉及 View 的操作和动画、手势​代码分离;
    兼容当前 Activity 和上一个 Activity Theme 不同的情况(由于 StatusBar 的高度产生的高度差)

License

Copyright 2016-2019 XBeats

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Apps
About Me
GitHub: Trinea
Facebook: Dev Tools