Android侧滑返回分析和实现(不高仿微信)

然后监听侧滑事件,移动顶层Activity的ContentView,即可真正透视到下层Activity的界面。此时无论布局变化、数据更新,都没问题。BUT!该方案问题多如牛毛。。。
存在问题windowIsTranslucent为true会引起一系列的动画问题,如前后台切换动画、Activity回退动画等。网上有解决方案说设置"android:windowEnterAnimation""android:windowExitAnimation",经测试并无卵用。同时,在SDK26(Android8.0)及以上,会与固定屏幕方向冲突造成闪退。同时,下层的Activity只会进入onPause状态,不会onStop,当页面开启过多时,一定会让你崩溃。

  • 透明方案二

如透明方案一,依旧在styles中配置那两条属性,在onPause中利用反射将窗口转为不透明,在onResume再利用反射将窗口转为透明。似乎酱紫很顺利地解决了下层以下的Activity不会onStop导致的性能问题。BUT!该方案问题依旧可怕。。。
存在问题:因顶层Activity透明,旋转屏幕时下层Activity会重建,然后在onResume中将窗口转为透明,然后下下层Activity也跟着复活了。。。一系列连锁反应,简直可怕!同时,windowIsTranslucent为true引起一系列的动画问题依然没有得到解决。

实现

经以上可知,要想侧滑时看到的不是假象,窗口必须透明让下层的Activity接收布局变化和数据更新。但是窗口透明会影响动画效果,且和屏幕旋转产生冲突。那么是否可以只在侧滑时窗口保持透明?
ofcourse~
我们可以在侧滑触发时利用反射将窗口转为透明,在侧滑结束时利用反射将窗口转为不透明。这样既可以在侧滑时一窥下层Activity真容,又不会和屏幕旋转冲突,也不会影响到动画的使用。原理很简单,下面开始一步步实现。

注:有同学问到Android P中禁止了非SDK接口的使用,但是窗口透明转换的接口均属于浅灰名单,目前不受限制。

  • Step.1 状态栏透明

既然要实现侧滑返回,状态栏必然要干掉,实现沉浸式体验。这里不多BB,直接上代码。

private boolean setStatusBarTransparent(boolean darkStatusBar) {
//SDK大于等于24,需要判断是否为窗口模式
boolean isInMultiWindowMode = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && mSwipeBackActivity.isInMultiWindowMode();
//窗口模式或者SDK小于19,不设置状态栏透明
if (isInMultiWindowMode || Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
return false;
} else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
//SDK小于21
mSwipeBackActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
} else {
//SDK大于等于21
int systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
//SDK大于等于23支持翻转状态栏颜色
if (darkStatusBar && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//设置状态栏文字&图标暗色
systemUiVisibility |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
}
//去除状态栏背景
mDecorView.setSystemUiVisibility(systemUiVisibility);
//设置状态栏透明
mSwipeBackActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
mSwipeBackActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
mSwipeBackActivity.getWindow().setStatusBarColor(Color.TRANSPARENT);
}
//监听DecorView的布局变化
mDecorView.addOnLayoutChangeListener(mPrivateListener);
return true;
}

这里有几个要注意的地方。
I. SDK小于19是不支持状态栏透明的,SD21及以上的实现方式也有所不同。

  • 22
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值