Android实现Ios右滑返回上一页效果

有天在撸码的过程中不知怎么着敲出了SlidingPaneLayout这个控件,本着没见过就去百度一番了解一下的原则,发现这是官方实现的一个侧滑菜单效果的控件,可是我记得侧滑菜单不是有DrawerLayout实现了吗,怎么又来一个,而且俩都是V4包下的。而且看网上说还有利用它实现Ios右滑返回效果的,有意思,那就自己用它实现实现试试吧。

1、初探SlidingPaneLayout

看了一下SlidingPaneLayout的使用,和DrawerLayout差不多,都是内部第一个控件作为内容,第二个控件作为菜单。

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SlidingPaneLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Main3Activity">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="菜单"
        android:gravity="center"
        android:textSize="36sp"
        android:background="#ffa"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="内容"
        android:textSize="36sp"
        android:gravity="center"
        android:background="#fff"/>

</android.support.v4.widget.SlidingPaneLayout>

效果是这样的

用过DrawerLayout实现侧滑菜单效果的人第一眼就能看出这俩的不一样,SlidingPaneLayout的菜单是在内容下层展示的,而DrawerLayout的菜单是在内容的上层展示。这是两个控件最直观的不同之处。

2、使用SlidingPaneLayout实现右滑返回

一开始我还纳闷用它怎么实现Ios的右滑返回效果的,看到上面的效果后才恍然大悟,原来是这样啊~

其实利用它实现的思路并不难,甚至有点取巧的意思。因为这个控件内部分为两部分嘛,一部分是菜单,一部分是内容,并且菜单在下层,内容在上层,我们将菜单这部分设为背景透明,并将菜单宽高设为填充全屏,内容这部分就正常放要展示的东西。这样向右滑动菜单的时候,菜单部分透明显示出上一页,内容部分则滑出屏幕,再结束当前页,实现右滑返回上一页效果。

那么现在要实现这个效果就有三个点

1)菜单部分全屏

2)菜单背景透明

3)菜单打开后退出当前Activity

2.1 实现菜单部分全屏

第一个,看上面的效果图可以看出,菜单部分并没有全屏显示,内容部分还占有一小块位置。怎么解决这个问题呢,先看看源码里有没有提供方法可以修改这个边界值。

 private final int mOverhangSize;

查看源码发现那个边界值是这个mOverhangSize定义的,而这个mOverhangSize被修饰为private和final,显然官方没有提供方法供我们修改这个参数。怎么办呢,反射就完事了。

private void initSlidingPane() {
        SlidingPaneLayout paneLayout = new SlidingPaneLayout(this);
        try {
            Field overhangSize = SlidingPaneLayout.class.getDeclaredField("mOverhangSize");
            overhangSize.setAccessible(true);
            overhangSize.set(paneLayout,0);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        
        //设置菜单布局
        TextView MenuView = new TextView(this);
        MenuView.setText("菜单");
        MenuView.setTextSize(TypedValue.COMPLEX_UNIT_SP,36);
        MenuView.setGravity(Gravity.CENTER);
        MenuView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        paneLayout.addView(MenuView,0);

        //设置内容布局
        TextView contentView = new TextView(this);
        contentView.setText("内容");
        contentView.setTextSize(TypedValue.COMPLEX_UNIT_SP,36);
        contentView.setGravity(Gravity.CENTER);
        contentView.setBackgroundColor(Color.parseColor("#ffffaa"));
        contentView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        paneLayout.addView(contentView,1);

        ViewGroup decorView = (ViewGroup) getWindow().getDecorView();
        decorView.addView(paneLayout);
    }

再看看效果

2.2 实现菜单背景透明

菜单全屏解决了,接下来再把菜单部分变得透明,怎么透明呢?给Activity自定义主题就完事了。

 <style name="Trans" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowTranslucentStatus" tools:targetApi="kitkat">true</item>

    </style>
<activity android:name=".Main4Activity" android:theme="@style/Trans"/>

这次我加了一个界面跳转,以显示菜单透明后的上级页面。

2.3 菜单打开后退出当前Activity

ok,只剩最后一个,菜单打开后退出当前Activity,SlidingPaneLayout有一个监听菜单滑动的接口,设置上就行,问题不大。

paneLayout.setPanelSlideListener(new SlidingPaneLayout.PanelSlideListener() {
            @Override
            public void onPanelSlide(@NonNull View view, float v) {
                Log.i("test", "sliding>>>" + v);
            }

            @Override
            public void onPanelOpened(@NonNull View view) {
                Log.i("test", "sliding已打开");
                finish();
            }

            @Override
            public void onPanelClosed(@NonNull View view) {
                Log.i("test", "sliding已关闭");
            }
        });

这个接口有三个方法,第一个方法的参数v是菜单打开的程度的数值,0为关闭,1为打开,在滑动打开的过程中从0向1变化。剩下两个方法是干嘛的就很显而易见了。

对了,记得再给Activity加上进场和退场的切换动画

<style name="Trans" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowIsTranslucent">true</item>
         <item name="android:windowAnimationStyle">@style/AnimBack</item>
        <item name="android:windowTranslucentStatus" tools:targetApi="kitkat">true</item>
       </style>

    <style name="AnimBack" parent="@android:style/Animation.Translucent">
        <item name="android:windowEnterAnimation">@anim/fade_in</item>
        <item name="android:windowExitAnimation">@anim/fade_out</item>
    </style>

fade_in

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:fromXDelta="100%"
        android:toXDelta="0"
        android:duration="@android:integer/config_mediumAnimTime"/>
</set>

fade_out

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="@android:integer/config_mediumAnimTime">

    <translate
        android:fromXDelta="0"
        android:toXDelta="100%" />
</set>

这里我切换了两次,可以看出菜单打开的时候Activity确实退出了。这里的Activity的切换动画要说一下,因为Activity的主题用到了windowIsTranslucent这个属性,所以Activity的退场动画会受到影响,因为我这里的状态栏是透明的,所以从效果上看并没收到影响,那么对那些效果受到影响的,在退出的Activity的finish方法中加上overridePendingTransition()这个方法就好了。

最后

到这里,一次偶尔的发现促使的仿Ios的右滑返回效果就完成啦,以前也接触过一些大牛写的仿Ios右滑返回的库,没想到Android自带的控件也能实现这样的效果,很惊喜,虽然有点取巧的意思,不过能实现的就是好方法嘛,哈哈!同时也发现Android其实有很多自带的优秀控件,能实现很多很棒的效果,其实Android也有自己的一套UI设计规范、UI交互体系,但是现在的设计知道Android的material design设计规范的太少了,全都向Ios看齐,倒想着省事,一套UI两端通用,全都照着Ios的效果来就是了,我本人其实很推崇Android自己的设计规范的,本来就是两个不同的端,结果在UI和交互上Android的特性和特色全都没有了,在这点上国内的知乎就做的比较不错,Android和Ios都是按照各自的规范来的,各有特色,区别明显,不愧是逼乎啊,最后还是希望以后像逼乎这样的例子越来越多吧。

发布了45 篇原创文章 · 获赞 18 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/Ever69/article/details/88116627
今日推荐