仿微信右滑返回功能


首先新建两个activity

  • MainActivity

    MainActivity 只需要在onCreate方法中实现向第二个activity的跳转即可。关键代码如下:

    Intent intent = new Intent(this, TargetActivity.class);
    startActivity(intent);
    
  • TargetActivity

    TargetActivity 即是我们的目标activity,需要执行我们想要实现的各类方法

  • 通过思考,我们知道,我们要挪动的activity其实就是挪动activity的依托界面,也就是支撑整个子View的DecorView,所以,我们首先要获取到界面的DecorView,然后,在滑动过程中,整个手势监听是最重要的,熟知事件传递的小伙伴知道,要监听手势活动,在Activity里面就要实现OnTouchEvent方法,那么滑动到什么位置的时候界面关闭,什么位置保持不变呢,这就需要我们用变量控制我们手势挪动的距离了,所以,我们用变量和我们屏幕宽度进行对比,暂时定为挪动距离 < 屏幕的1/2宽度,targetActivity不被finish,否则,finish。下面即是代码实现。
  1. 首先定义我们在滑动过程中会用到的对比变量

    View decorView;
    float downX;
    float screenWidth, screenHeight;
    
  2. 然后在onCreate 函数里面实现对以上变量进行初始化

    DisplayMetrics metrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(metrics);
    screenWidth = metrics.widthPixels;
    screenHeight = metrics.heightPixels;
    
  3. 复写onTouchEvent方法,控制界面的展示与消失,但是为了使界面消失和还原的过程不那么生硬,我们采用两个动画的方式,使加载变缓和。

    3.1 还原动画

    private void moveBackToLeft(float moveDistanceX){
        ObjectAnimator.ofFloat(decorView, "X", moveDistanceX, 0).setDuration(300).start();
    }
    

    3.2 关闭动作动画

        private void continueMoveToRight(float moveDistanceX){
            // 定义动画
            ValueAnimator animator = ValueAnimator.ofFloat(moveDistanceX, screenWidth);
            animator.setDuration(300);
            animator.start();
    
            //添加动画过程监听
            animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
               public void onAnimationUpdate(ValueAnimator animation) {
                float x = (float)animation.getAnimatedValue();
                decorView.setX(x);
            }
        });
    
        //添加动画完成动作监听,其中SimpleAnimationListener是个自己实现了Animator.AnimatorListener的abstract类
        animator.addListener(new SimpleAnimationListener()    {
                @Override
                public void onAnimationEnd(Animator animation) {
                finish();
            }
        });
    }
    

    3.3 复写onTouchEvent方法。

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN){
            downX = event.getX();
    
        } else if (event.getAction() == MotionEvent.ACTION_MOVE){
            float moveDistanceX = event.getX() - downX;
    
            if (moveDistanceX > 0){
                decorView.setX(moveDistanceX);
            }
    
        } else if (event.getAction() == MotionEvent.ACTION_UP){
            float moveDistanceX = event.getX() - downX;
    
            if (moveDistanceX > screenWidth / 2){
                continueMoveToRight(moveDistanceX);
            } else {
                moveBackToLeft(moveDistanceX);
            }
        }
        return super.onTouchEvent(event);
    }
    
  4. 实现以上方法之后,诶,你会发现,界面好像是在挪动,可是呢,挪走之后的部分依然是原布局的颜色,看不到底层布局,这时候,我们就应该设置我们TargetActivity的属性啦。

设置我们的TargetActivity属性

1 打开我们res/values/styles 文件,在里面新建一个自定义的属性,如下所示,我们命名为SuspendTheme

<style name="SuspendTheme" parent="@android:style/Theme.Black.NoTitleBar.Fullscreen">
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:colorBackgroundCacheHint">@null</item>
</style> 

2 打开我们activity对应的module下的AndroidManifest文件,对我们的TargetActivity进行我们自定义的属性配置

<activity android:name=".present.SuspendActivity"
        android:theme="@style/SuspendTheme"/>

再次运行整个app,你会发现,右滑返回的基本功能实现啦,那么接下来,我们要实现的,就是在右滑过程的底层activity界面的透明度渐变展示啦。下一次我将继续总结,如何更完美的实现仿微信的右滑返回。