Android仿微信实现IOS风格的滑动返回上一页

前言:

           我们都知道在当前Android系统当中如果要实现应用返回上一页,最简单的做法就是什么也不做,所谓无招胜有招指的大概就是这个吧!但你真敢这么做嘛!这可不是微信所提倡的大道至简啊,虽然Android系统自带虚拟返回键,但是往往我们还是会在标题栏加上返回按钮吧,可能说大部分应用这么做就结束了。我想大家肯定有这种时候吧,当你沉醉在当前界面的美好事物当中时,这时候你想返回上一页,如果是上面这种处理方式,你可能会去找一下返回按钮,如果再加上该返回按钮过小的话,怎么也会消灭掉你的一点兴致吧。再比如如果手机屏幕够大,你都不得不去用另一种手去按返回了,这个时候如果是一只手就能完成是不是方便多了呢!说了这么多大家看标题也知道我要说什么了,微信Android版本在6.2的时候就已经实现了在IOS系统当中自带的滑动返回功能,到今天为止其实有很多应用都已经加上了这种滑动效果。像今日头条,QQ等等,只不过大家处理方式稍有不同。相对来说我最喜欢的还是微信的处理方式,体验不错。遗憾的是到今天为止Android系统依然没有添加相应的api来实现这一优雅的返回效果,所以现在各路大神们已经造出了非常多相关的轮子。但都有相应的大大小小的问题。我今天来介绍一种不用轮子的方式,亲测效果不错。下面就献丑了。

具体实现:

由于返回的效果基本在界面中处处用的到,所以我们写个BaseActivity来封装一下,主要逻辑如下:

public class BaseActivity extends AppCompatActivity implements SlidingPaneLayout.PanelSlideListener{

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        initSlideBackClose();//滑动返回的初始化设置
        super.onCreate(savedInstanceState);
    }
    private void initSlideBackClose() {
        if(isNeedSlideBack()){
            SlidingPaneLayout slidingPaneLayout = new SlidingPaneLayout(this);
            try{
                // 通过反射来改变mOverhangSize的值,
                // 这个mOverhangSize值为菜单到右边屏幕的最短距离,
                // 默认是32dp,现在给它改成0
                Field overhangSize = SlidingPaneLayout.class.getDeclaredField("mOverhangSize");
                overhangSize.setAccessible(true);
                overhangSize.set(slidingPaneLayout,0);
            }catch (Exception e){
                e.printStackTrace();
            }
            slidingPaneLayout.setPanelSlideListener(this);
            slidingPaneLayout.setSliderFadeColor(getResources().getColor(android.R.color.transparent));
            // 左侧的透明视图
            View leftView = new View(this);
            leftView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
            // 为 SlidingPaneLayout 添加透明视图
            slidingPaneLayout.addView(leftView, 0);
            ViewGroup decorView = (ViewGroup) getWindow().getDecorView();
            //右侧的内容视图
            ViewGroup decorChild = (ViewGroup) decorView.getChildAt(0);
            decorChild.setBackgroundColor(getResources().getColor(android.R.color.white));
            decorView.removeView(decorChild);
            decorView.addView(slidingPaneLayout);
            // 为 SlidingPaneLayout 添加内容视图
            slidingPaneLayout.addView(decorChild, 1);
        }
    }
    //设置是否需要滑动返回
    protected boolean isNeedSlideBack() {
        return true;
    }
    @Override
    public void onPanelSlide(@NonNull View view, float v) {}
    @Override
    public void onPanelOpened(@NonNull View view) {
        //打开之后销毁掉
        finish();
    }
    @Override
    public void onPanelClosed(@NonNull View view) {}
}

之后你只需要让其他activity继承该BaseActivity就可以了,例如:

public class MainActivity extends BaseActivity 

如果只是这样的话,运行之后你会发现首先滑动返回是没问题的,但是你会发现会白屏一下才显示桌面的,这样肯定不行,首先主界面是不需要滑动返回的,其次就算要返回也不能有白屏的现象,处理方式如下:

//该界面不需要返回(主界面中重写该方法返回false)
protected boolean isNeedSlideBack() {
    return false;
}
在你当前application的主题样式下加入该设置就能处理白屏问题
<!--设置窗口背景为透明-->
<item name ="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>

不过加入<item name ="android:windowIsTranslucent">true</item>这个设置之后,你的应用可能会出现崩溃的问题,查看日志后你会发现有这句Caused by: java.lang.IllegalStateException: Only fullscreen opaque activitie,意思是说只有不透明的全屏activity可以自主设置界面方向。这个错误是Android8.0之后才会出现的,原因是因为你同时设置了 android:screenOrientation="" 和 <item name="android:windowIsTranslucent">true</item>。在8.0的设备上没办法你只能取其一,我的处理方式是把清单文件当中的android:screenOrientation都去掉,在baseactivity的oncreate方法中加入这一句setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//设置竖屏。其实到这里效果就已经实现了,只不过可能丑了一点,当然你可以加入进退场动画就好了,例如:

<!--activity启动关闭样式-->//在你当前application的主题样式下加入该设置
<item name="android:windowAnimationStyle">@style/activityAnimation</item>
<!--activity启动关闭动画-->
<style name="activityAnimation" parent="@android:style/Animation">
<item name="android:activityEnterAnimation">@anim/in_right</item>
<item name="android:activityExitAnimation">@anim/out_left</item>
</style>

in_right.xml:

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="500"
        android:fillAfter="true"
        android:fromXDelta="100%p"
        android:interpolator="@android:anim/accelerate_interpolator"
        android:toXDelta="0" />
</set>

out_left.xml:

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="500"
        android:fillAfter="true"
        android:fromXDelta="0"
        android:interpolator="@android:anim/accelerate_interpolator"
        android:toXDelta="100%p" />
</set>

好了,这样就差不多了,加上动画之后就不会那么生硬了,我觉得大部分界面这么写应该都是没问题的,大家可以参考着在你的项目中加上,我觉得应该会不错的,以上。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值