侧滑效果[第十五篇]:侧滑框架SmartSwipe之全局返回

前面,我为大家展示了5种侧滑返回效果:仿手机QQ侧滑返回仿微信侧滑返回效果仿MIUI系统贝塞尔曲线侧滑返回开门式侧滑返回百叶窗式侧滑返回

但是,有些在兼容性上有一定的缺陷。

由于采用了activity透明的方式来透视前一个activity,在5.0以下版本系统上存在兼容性问题,导致仿微信侧滑返回开门式侧滑返回百叶窗式侧滑返回只在5.0以上版本的设备生效。

由于5.0以下版本的设备占比已经较少,与其采用会修改主题为透明并在onCreated中在变为不透明等较为复杂的方案,不如分别为5.0以上及以下的采用不同的侧滑返回方案。

SmartSwipe是用SmartSwipeBack封装了侧滑返回功能。

SmartSwipeBack.java

public class SmartSwipeBack {
    public static final ArrayList<Activity> ACTIVITIES = new ArrayList<>();
    private static IPreviousFinder mPreviousFinder;

    public interface SwipeBackConsumerFactory {
        /**
         * Create SwipeConsumer to do swipe back business for activity
         * @param activity activity to wrap with swipe back
         * @return SwipeConsumer
         */
        SwipeConsumer createSwipeBackConsumer(Activity activity);
    }
    public interface ActivitySwipeBackFilter {
        /**
         * Determine whether the activity parameter should swipe back
         * @param activity The activity to wrap or not
         * @return true: need to wrap with swipe back, false: do not wrap
         */
        boolean onFilter(Activity activity);
    }

    public static void activityBack(Application application, SwipeBackConsumerFactory factory) {
        activityBack(application, factory, null);
    }

    /**
     * The core function for global activity swipe back
     * @param application application
     * @param factory factory to create SwipeConsumer for each Activity
     * @param filter filter of activity, to determine which activity should finish via swipe motion
     */
    public static void activityBack(Application application, SwipeBackConsumerFactory factory, ActivitySwipeBackFilter filter) {
        if (activitySwipeBackListener == null) {
            activitySwipeBackListener = new ActivitySwipeBackListener(factory, filter);
        } else {
            application.unregisterActivityLifecycleCallbacks(activitySwipeBackListener);
            activitySwipeBackListener.mFactory = factory;
            activitySwipeBackListener.mFilter = filter;
        }
        application.registerActivityLifecycleCallbacks(activitySwipeBackListener);
    }

    ////////////////////////////////////////////
    //
    //  swipe back with StayConsumer
    //
    ////////////////////////////////////////////

    public static void activityStayBack(Application application, SmartSwipeBack.ActivitySwipeBackFilter filter) {
        final int edgeSize = SmartSwipe.dp2px(20, application);
        activityStayBack(application, filter, edgeSize, 0, SwipeConsumer.DIRECTION_LEFT);
    }

    public static void activityStayBack(Application application, SmartSwipeBack.ActivitySwipeBackFilter filter, final int edgeSize, final int minVelocity, final int direction) {
        SmartSwipeBack.activityBack(application, new SwipeBackConsumerFactory() {
            @Override
            public SwipeConsumer createSwipeBackConsumer(final Activity activity) {
                return new StayConsumer()
                        .setMinVelocity(minVelocity)
                        .setEdgeSize(edgeSize)
                        .enableDirection(direction)
                        .addListener(new SimpleSwipeListener() {
                            @Override
                            public void onSwipeOpened(SmartSwipeWrapper wrapper, SwipeConsumer consumer, int direction) {
                                if (activity != null) {
                                    activity.finish();
                                }
                            }
                        });
            }
        }, filter);
    }

    ////////////////////////////////////////////
    //
    //  swipe back with ActivitySlidingBackConsumer
    //
    ////////////////////////////////////////////

    public static void activitySlidingBack(Application application, SmartSwipeBack.ActivitySwipeBackFilter filter) {
        final float factor = 0.5f;
        // with default scrimColor: transparent
        activitySlidingBack(application, filter, factor);
    }

    public static void activitySlidingBack(Application application, SmartSwipeBack.ActivitySwipeBackFilter filter, float factor) {
        //default edge size
        final int edgeSize = SmartSwipe.dp2px(20, application);
        final int shadowColor = 0x80000000;
        final int shadowSize = SmartSwipe.dp2px(10, application);
        final int direction = SwipeConsumer.DIRECTION_LEFT;
        activitySlidingBack(application, filter, edgeSize, Color.TRANSPARENT, shadowColor, shadowSize, factor, direction);
    }

    public static void activitySlidingBack(Application application, SmartSwipeBack.ActivitySwipeBackFilter filter
            , final int edgeSize, final int scrimColor, final int shadowColor, final int shadowSize
            , final float factor, final int direction) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            //if sdk version is less than 21, the compatibility of ActivitySlidingBackConsumer is not good enough
            //use StayConsumer instead for android sdk version <= 20
            activityStayBack(application, filter, edgeSize, 0, direction);
        } else {
            activityBack(application, new SwipeBackConsumerFactory() {
                @Override
                public SwipeConsumer createSwipeBackConsumer(final Activity activity) {
                    return new ActivitySlidingBackConsumer(activity)
                            .setRelativeMoveFactor(factor)
                            .setScrimColor(scrimColor)
                            .setShadowColor(shadowColor)
                            .setShadowSize(shadowSize)
                            .setEdgeSize(edgeSize)
                            .enableDirection(direction)
                            .addListener(new SimpleSwipeListener(){
                                @Override
                                public void onSwipeOpened(SmartSwipeWrapper wrapper, SwipeConsumer consumer, int direction) {
                                    if (activity != null) {
                                        activity.finish();
                                        activity.overridePendingTransition(R.anim.anim_none, R.anim.anim_none);
                                    }
                                }
                            });
                }
            }, filter);
        }
    }

    ////////////////////////////////////////
    //
    //  swipe back with BezierBackConsumer
    //
    ////////////////////////////////////////

    public static void activityBezierBack(Application application, SmartSwipeBack.ActivitySwipeBackFilter filter) {
        final int edgeSize = SmartSwipe.dp2px(20, application);
        activityBezierBack(application, filter, edgeSize);
    }

    public static void activityBezierBack(Application application, SmartSwipeBack.ActivitySwipeBackFilter filter, int edgeSize) {
        final int thickness = SmartSwipe.dp2px(30, application);
        final int size = SmartSwipe.dp2px(200, application);
        final int direction = SwipeConsumer.DIRECTION_LEFT;
        activityBezierBack(application, filter, edgeSize, size, thickness, Color.BLACK, Color.WHITE, direction);
    }

    public static void activityBezierBack(Application application, SmartSwipeBack.ActivitySwipeBackFilter filter
            , final int edgeSize, final int size, final int thickness, final int color, final int arrowColor, final int direction) {
        SmartSwipeBack.activityBack(application, new SwipeBackConsumerFactory() {
            @Override
            public SwipeConsumer createSwipeBackConsumer(final Activity activity) {
                return new BezierBackConsumer()
                        .setColor(color)
                        .setArrowColor(arrowColor)
                        .setSize(size)
                        .setOpenDistance(thickness)
                        .addListener(new SimpleSwipeListener() {
                            @Override
                            public void onSwipeRelease(SmartSwipeWrapper wrapper, SwipeConsumer consumer, int direction, float progress, float xVelocity, float yVelocity) {
                                if (progress >= 1) {
                                    activity.finish();
                                }
                            }
                        })
                        .setEdgeSize(edgeSize)
                        .enableDirection(direction);
            }
        }, filter);
    }

    ////////////////////////////////////////
    //
    //  swipe back with ActivityDoorBackConsumer
    //
    ////////////////////////////////////////

    public static void activityDoorBack(Application application, SmartSwipeBack.ActivitySwipeBackFilter filter) {
        final int edgeSize = SmartSwipe.dp2px(20, application);
        final int scrimColor = 0x80000000;
        final boolean refreshable = true;
        activityDoorBack(application, filter, SwipeConsumer.DIRECTION_LEFT, edgeSize, scrimColor, refreshable);
    }

    public static void activityDoorBack(Application application, SmartSwipeBack.ActivitySwipeBackFilter filter
            , final int direction, final int edgeSize, final int scrimColor, final boolean refreshable) {
        SmartSwipeBack.activityBack(application, new SwipeBackConsumerFactory() {
            @Override
            public SwipeConsumer createSwipeBackConsumer(final Activity activity) {
                return new ActivityDoorBackConsumer(activity)
                        .setRefreshable(refreshable)
                        .setScrimColor(scrimColor)
                        .enableDirection(direction)
                        .setEdgeSize(edgeSize)
                        .addListener(new SimpleSwipeListener() {
                            @Override
                            public void onSwipeOpened(SmartSwipeWrapper wrapper, SwipeConsumer consumer, int direction) {
                                activity.finish();
                                activity.overridePendingTransition(R.anim.anim_none, R.anim.anim_none);
                            }
                        });
            }
        }, filter);
    }

    ////////////////////////////////////////
    //
    //  swipe back with ActivityShuttersBackConsumer
    //
    ////////////////////////////////////////

    public static void activityShuttersBack(Application application, SmartSwipeBack.ActivitySwipeBackFilter filter) {
        final int edgeSize = SmartSwipe.dp2px(20, application);
        final int scrimColor = 0x80000000;
        final boolean refreshable = true;
        activityShuttersBack(application, filter, SwipeConsumer.DIRECTION_LEFT, edgeSize, scrimColor, refreshable);
    }

    public static void activityShuttersBack(Application application, SmartSwipeBack.ActivitySwipeBackFilter filter
            , final int direction, final int edgeSize, final int scrimColor, final boolean refreshable) {
        SmartSwipeBack.activityBack(application, new SwipeBackConsumerFactory() {
            @Override
            public SwipeConsumer createSwipeBackConsumer(final Activity activity) {
                return new ActivityShuttersBackConsumer(activity)
                        .setRefreshable(refreshable)
                        .setScrimColor(scrimColor)
                        .enableDirection(direction)
                        .setEdgeSize(edgeSize)
                        .addListener(new SimpleSwipeListener() {
                            @Override
                            public void onSwipeOpened(SmartSwipeWrapper wrapper, SwipeConsumer consumer, int direction) {
                                activity.finish();
                                activity.overridePendingTransition(R.anim.anim_none, R.anim.anim_none);
                            }
                        });
            }
        }, filter);
    }

    private static ActivitySwipeBackListener activitySwipeBackListener;

    public static class ActivitySwipeBackListener implements Application.ActivityLifecycleCallbacks {
        private SwipeBackConsumerFactory mFactory;
        private ActivitySwipeBackFilter mFilter;

        ActivitySwipeBackListener(SwipeBackConsumerFactory factory, ActivitySwipeBackFilter filter) {
            this.mFactory = factory;
            this.mFilter = filter;
        }

        @Override
        public void onActivityCreated(final Activity activity, Bundle savedInstanceState) {
            ACTIVITIES.add(activity);
            if (mFactory == null) {
                return;
            }
            if (mFilter != null && !mFilter.onFilter(activity)) {
                return;
            }
            SmartSwipe.wrap(activity).addConsumer(mFactory.createSwipeBackConsumer(activity));
        }
        @Override public void onActivityStarted(Activity activity) { }
        @Override public void onActivityResumed(Activity activity) { }
        @Override public void onActivityPaused(Activity activity) { }
        @Override public void onActivityStopped(Activity activity) { }
        @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { }
        @Override public void onActivityDestroyed(Activity activity) {
            ACTIVITIES.remove(activity);
        }
    }

    /**
     * find previous activity
     * @param fromActivity the given activity to find its previous
     * @return the previous activity if exists
     * @see ActivitySlidingBackConsumer
     */
    public static Activity findPreviousActivity(Activity fromActivity) {
        if (mPreviousFinder != null) {
            return mPreviousFinder.findPreviousActivity(fromActivity);
        }
        if (fromActivity != null) {
            int index = ACTIVITIES.indexOf(fromActivity);
            if (index > 0) {
                return ACTIVITIES.get(index - 1);
            }
        }
        return null;
    }

    public static void setPreviousFinder(IPreviousFinder previousFinder) {
        mPreviousFinder = previousFinder;
    }

    public static interface IPreviousFinder {
        /**
         * find the previous activity for the given activity
         * @param fromActivity activity given
         * @return the previous activity
         */
        Activity findPreviousActivity(Activity fromActivity);
    }
}

为了兼容,需要对SDK版本进行判断,如下:

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
        SmartSwipeBack.activityBezierBack(this, new SmartSwipeBack.ActivitySwipeBackFilter() {
            @Override
            public boolean onFilter(Activity activity) {
                if(activity instanceof ImageViewerActivity){
                    return true;
                }
                return true;
            }
        });
    }else{
        SmartSwipeBack.activitySlidingBack(this, new SmartSwipeBack.ActivitySwipeBackFilter() {
            @Override
            public boolean onFilter(Activity activity) {
                if(activity instanceof ImageViewerActivity){
                    return false;
                }
                return true;
            }
        });
    }

以上代码放在Application的onCreate中即可。

【过滤器】

以一下方法举例

activitySlidingBack(Application application, SmartSwipeBack.ActivitySwipeBackFilter filter)

第一个参数是当前Application,第二个参数是过滤器。

        SmartSwipeBack.activitySlidingBack(this, new SmartSwipeBack.ActivitySwipeBackFilter() {
            @Override
            public boolean onFilter(Activity activity) {
                if(activity instanceof ImageViewerActivity){
                    return false;
                }
                return true;
            }
        });

以上代码中的过滤器的返回值是一个布尔类型,false表示不需要侧滑返回,true表示需要侧滑返回,当然,也可以直接将过滤器置为null,如:

SmartSwipeBack.activitySlidingBack(this, null);

若为null,则不过滤,对所有activity都执行侧滑返回的封装。

【内置生命周期监听】

SmartSwipeBack类中内置了对Activity生命周期的监听,以及管理Activity的返回栈,当Activity被创建的时候,就被放入返回栈中。

那么,如何获取当前Activity的上一个Activity?方法如下:

    Activity activity = SmartSwipeBack.findPreviousActivity(this);

如何获取返回栈中所有的Activity?

    ArrayList<Activity> list = SmartSwipeBack.ACTIVITIES;

[本章完...]

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,063评论 6 510
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,805评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,403评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,110评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,130评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,877评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,533评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,429评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,947评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,078评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,204评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,894评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,546评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,086评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,195评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,519评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,198评论 2 357

推荐阅读更多精彩内容