前言:
我们都知道在当前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>
好了,这样就差不多了,加上动画之后就不会那么生硬了,我觉得大部分界面这么写应该都是没问题的,大家可以参考着在你的项目中加上,我觉得应该会不错的,以上。