返回顶部
首页 > 资讯 > 移动开发 >剖析Android Activity侧滑返回的实现原理
  • 560
分享到

剖析Android Activity侧滑返回的实现原理

2024-04-02 19:04:59 560人浏览 薄情痞子
摘要

简介 使用侧滑Activity返回很常见,例如微信就用到了。那么它是怎么实现的呢。本文带你剖析一下实现原理。我在GitHub上找了一个star有2.6k的开源,我们分析他是怎么实现的

简介

使用侧滑Activity返回很常见,例如微信就用到了。那么它是怎么实现的呢。本文带你剖析一下实现原理。我在GitHub上找了一个star有2.6k的开源,我们分析他是怎么实现的


//star 2.6k
'com.r0adkll:slidableactivity:2.0.5'

Slidr使用示例

它的使用很简单,首先要设置透明的窗口背景


 <style name="AppTheme"  parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="Android:textAllCaps">false</item>
        <item name="android:windowActionBar">false</item>
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowBackground">@android:color/transparent</item>
    </style>

然后


//setContent(View view)后
Slidr.attach(this);

下面可以从三个步骤看其原理

步骤一 重新包裹界面

Slidr.class


 public static SlidrInterface attach(final Activity activity, final int statusBarColor1, final int statusBarColor2){
        //0  创建滑动嵌套界面SliderPanel
		final SliderPanel panel = initSliderPanel(activity, null);

        //7 Set the panel slide listener for when it becomes closed or opened
        // 监听回调
        panel.setOnPanelSlideListener(new SliderPanel.OnPanelSlideListener() {
			...
            //open close等
        });

		// Return the lock interface
		return initInterface(panel);
    }

	private static SliderPanel initSliderPanel(final Activity activity, final SlidrConfig config) {
		//3 获取decorview
		ViewGroup decorView = (ViewGroup)activity.getWindow().getDecorView();
        
        //4 获取我们布局的内容并删除
		View oldScreen = decorView.getChildAt(0);
		decorView.removeViewAt(0);

		//5 Setup the slider panel and attach it to the decor
        // 建立滑动嵌套视图SliderPanel并且添加到DecorView中
		SliderPanel panel = new SliderPanel(activity, oldScreen, config);
		panel.setId(R.id.slidable_panel);
		oldScreen.setId(R.id.slidable_content);
        
        //6 把我们的界面布局添加到SliderPanel,并且把SliderPanel添加到decorView中
		panel.addView(oldScreen);
		decorView.addView(panel, 0);
		return panel;
	}

步骤二 使用ViewDragHelper.class处理滑动手势

SliderPanel.class


private void init(){
    ...
    //1 ViewDragHelper创建
    mDragHelper = ViewDragHelper.create(this, mConfig.getSensitivity(), callback);
    mDragHelper.setMinVelocity(minVel);
    mDragHelper.setEdgeTrackingEnabled(mEdgePosition);

    //2 Setup the dimmer view 添加用于指示滑动过程的View到底层
    mDimView = new View(getContext());
    mDimView.setBackgroundColor(mConfig.getScrimColor());
    mDimView.setAlpha(mConfig.getScrimStartAlpha());
    addView(mDimView);
}

步骤三 在ViewDragHelper.Callback中处理我们的界面的拖动

我们首先明确ViewDragHelper仅仅是处理ParentView与它子View的关系,不会一直遍历到最顶层的View。ViewDragHelper的捕获capture是这样实现的


  @Nullable
    public View findTopChildUnder(int x, int y) {
        final int childCount = mParentView.getChildCount();
        for (int i = childCount - 1; i >= 0; i--) {
            final View child = mParentView.getChildAt(mCallback.getOrderedChildIndex(i));
            if (x >= child.getLeft() && x < child.getRight()
                    && y >= child.getTop() && y < child.getBottom()) {
                return child;
            }
        }
        return null;
    }

重点在SliderPanel.class的ViewDragHelper.Callback callback的实现,作者实现实现了很多个方向的滑动处理mLeftCallback、mRightCallback、mTopCallback、mBottomCallback、mVerticalCallback、mHorizontalCallback, 我们取mLeftCallback来分析


private ViewDragHelper.Callback mLeftCallback = new ViewDragHelper.Callback() {

    //捕获View
    @Override
    public boolean tryCaptureView(View child, int pointerId) {
        boolean edgeCase = !mConfig.isEdgeOnly() || mDragHelper.isEdgeTouched(mEdgePosition, pointerId);
        //像前面说的,我们的内容是最上层子View,mDecorView这里指的是我们的contentView
        return child.getId() == mDecorView.getId() && edgeCase;
    }

    //拖动, 最终是通过view.offsetLeftAndRight(offset)实现移动
    @Override
    public int clampViewPositionHorizontal(View child, int left, int dx) {
        return clamp(left, 0, mScreenWidth);
    }

    //滑动范围
    @Override
    public int getViewHorizontalDragRange(View child) {
        return mScreenWidth;
    }

    //释放处理,判断是滚回屏幕
    @Override
    public void onViewReleased(View releasedChild, float xvel, float yvel) {
        super.onViewReleased(releasedChild, xvel, yvel);

        int left = releasedChild.getLeft();
        int settleLeft = 0;
        int leftThreshold = (int) (getWidth() * mConfig.getDistanceThreshold());
        boolean isVerticalSwiping = Math.abs(yvel) > mConfig.getVelocityThreshold();

        if(xvel > 0){

            if(Math.abs(xvel) > mConfig.getVelocityThreshold() && !isVerticalSwiping){
                settleLeft = mScreenWidth;
            }else if(left > leftThreshold){
                settleLeft = mScreenWidth;
            }

        }else if(xvel == 0){
            if(left > leftThreshold){
                settleLeft = mScreenWidth;
            }
        }
		
        //滚动到left=0(正常布局) 或者 滚动到left=mScreenWidth(滚出屏幕)关闭Activity
        mDragHelper.settleCapturedViewAt(settleLeft, releasedChild.getTop());
        invalidate();
    }

    //转换位置百分比,确定指示层的透明度
    @Override
    public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
        super.onViewPositionChanged(changedView, left, top, dx, dy);
        float percent = 1f - ((float)left / (float)mScreenWidth);

        if(mListener != null) mListener.onSlideChange(percent);

        // Update the dimmer alpha
        applyScrim(percent);
    }

    //回调到Slidr处理Activity状态
    @Override
    public void onViewDragStateChanged(int state) {
        super.onViewDragStateChanged(state);
        if(mListener != null) mListener.onStateChanged(state);
        switch (state){
            case ViewDragHelper.STATE_IDLE:
                if(mDecorView.getLeft() == 0){
                    // State Open
                    if(mListener != null) mListener.onOpened();
                }else{
                    // State Closed  这里回调到Slidr处理activity.finish()
                    if(mListener != null) mListener.onClosed();
                }
                break;
            case ViewDragHelper.STATE_DRAGGING:

                break;
            case ViewDragHelper.STATE_SETTLING:

                break;
        }
    }
};

对于mDragHelper.settleCapturedViewAt(settleLeft, releasedChild.getTop());内部是使用Scroller.class辅助滚动,所以要在SliderPanel中重写View.computeScroll()


@Override
public void computeScroll() {
    super.computeScroll();
    if(mDragHelper.continueSettling(true)){
        ViewCompat.postInvalidateOnAnimation(this);
    }
}

总结

整体方案如下图所示

总体来看原理并不复杂, 就是通过ViewDragHelper对View进行拖动。

以上就是Android Activity侧滑返回的实现原理的详细内容,更多关于Activity侧滑返回的资料请关注编程网其它相关文章!

--结束END--

本文标题: 剖析Android Activity侧滑返回的实现原理

本文链接: https://lsjlt.com/news/129062.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 剖析Android Activity侧滑返回的实现原理
    简介 使用侧滑Activity返回很常见,例如微信就用到了。那么它是怎么实现的呢。本文带你剖析一下实现原理。我在github上找了一个star有2.6k的开源,我们分析他是怎么实现的...
    99+
    2024-04-02
  • Android 侧滑关闭Activity的实例
    Android 侧滑关闭Activity的实例实现原因其实侧滑关闭activity在网上也有大量的文章去介绍他,我也有去看,要么是代码实在太多看不下去,要么就是跑了项目没有反应的。唯一的方法还是自己随手鲁一个~,侧滑这个东西在Android...
    99+
    2023-05-30
    android 侧滑关闭 roi
  • Android仿iOS如何实现侧滑返回功能
    这篇文章将为大家详细讲解有关Android仿iOS如何实现侧滑返回功能,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。先上个效果再说:原理Activity 本身是不可以滑动的,但是我们可以制造一个正在滑动 ...
    99+
    2023-05-30
  • Android中怎么利用Activity实现滑动返回
    这期内容当中小编将会给大家带来有关Android中怎么利用Activity实现滑动返回,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Android 滑动返回Activity的实现代码package&nbs...
    99+
    2023-05-30
    android activity
  • Android中activity处理返回结果的实现方式
    大家在网上购物时都有这样一个体验,在确认订单选择收货人以及地址时,会跳转页面到我们存入网站内的所有收货信息(包含收货地址,收货人)的界面供我们选择,一旦我们点击其中某一条信息,...
    99+
    2022-06-06
    activity Android
  • Android实现全局右滑返回
    目前Android手机的全面屏越来越盛行,很多应用都已经支持了右滑返回上一级页面的功能,那么这个功能如何实现呢? 首先来说下思路吧,主要是通过 MotionEvent 这个事件...
    99+
    2022-06-06
    Android
  • Android PhoneWindowManager监听屏幕右侧向左滑动实现返回功能
            由于项目没有设计返回键,一旦进入别的应用,就无法回到桌面。只能通过串口输入input keyevent 4(返回键)来返回桌面,为了方便调试,在Framewor...
    99+
    2022-06-06
    Android
  • 代码分析Android实现侧滑菜单
    Android 侧滑菜单的实现,参考网上的代码,实现侧滑菜单。最重要的是这个动画类UgcAnimations,如何使用动画类来侧滑的封装FlipperLayout。 1、实现效...
    99+
    2022-06-06
    菜单 Android
  • Android中SwipeBack实现右滑返回效果
    现在有很多App支持右滑返回,比如知乎,效果比较赞。 于是自己对Activity和Fragment进行了继承,派生出SwipeBackActivity和SwipeBackFr...
    99+
    2022-06-06
    Android
  • Android实现类似IOS右滑返回的效果(原因分析及解决办法)
    使用类库SwipeBackLayout https://github.com/Issacw0ng/SwipeBackLayout 出现的问题: 1. 主Activity返回...
    99+
    2022-06-06
    IOS Android
  • Go defer的实现原理剖析
    本篇内容介绍了“Go defer的实现原理剖析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1. 前言de...
    99+
    2024-04-02
  • Android实现原生侧滑菜单的超简单方式
    先来看看效果图 当你点击菜单可以更改图标,例如点击happy,首页就会变一个笑脸,这个实现的过程超级简单 你需要使用ToolBar与DrawableLayout两个比较新的控...
    99+
    2022-06-06
    菜单 Android
  • Android 侧滑按钮的实现代码
    目录导入闭包创建RecyclerView子项布局文件布局代码创建RecyclerView适配器描述子项点击事件应用Android侧滑按钮效果如下所示: 导入闭包 将以下语句倒入目录...
    99+
    2024-04-02
  • Android左滑返回功能的实现示例代码
    前几天用了个app发现左滑可以返回首页,发现这个功能很炫酷,就想着自己能不能做出来,于是研究了一下原理 将activity的背景设置为透明同时设置切换动画 手指滑动的时候,根View跟着滑动,滑倒一定的距离就finish掉。 原理很简...
    99+
    2023-05-31
    android 左滑返回 roi
  • Android如何实现仿微信右滑返回功能
    这篇文章将为大家详细讲解有关Android如何实现仿微信右滑返回功能,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。先上效果图,如下:先分析一下功能的主要技术点,右滑即手势判断,当滑到一直距离时才执行返回,...
    99+
    2023-05-30
    android
  • Android 侧滑抽屉菜单的实现代码
    目录前言正文一、创建项目二、添加滑动菜单三、UI美化四、添加导航视图五、菜单分类六、动态菜单七、源码运行效果图: 前言   滑动菜单相信都不会陌生,你可能见...
    99+
    2024-04-02
  • Android中怎么实现右滑返回上一个界面
    今天就跟大家聊聊有关Android中怎么实现右滑返回上一个界面,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Android右滑返回上一个界面的实现方法public clas...
    99+
    2023-05-30
    android
  • Java中SynchronousQueue的底层实现原理剖析
    目录1. SynchronousQueue用法2. SynchronousQueue应用场景3. SynchronousQueue源码解析3.1 SynchronousQueue类属...
    99+
    2022-11-21
    Java SynchronousQueue实现 Java SynchronousQueue原理 Java SynchronousQueue
  • 深入剖析OpenMP锁的原理与实现
    目录前言深入分析 omp_lock_tomp_lock_t 源码分析深入分析 omp_nest_lock_tomp_nest_lock_t 源码分析源代码函数名称不同的原因揭秘总结前...
    99+
    2023-01-28
    OpenMP锁原理 OpenMP锁实现 OpenMP锁
  • Android实现回弹ScrollView的原理
    本文实例为大家分享了Android实现回弹ScrollView的原理,供大家参考,具体内容如下 回弹的ScrollView 网上看到的通常是ElasticScrollView,有一个...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作