SwipeBackLayout 和SwipeBackActivity最完全解析

本文详细解析了如何实现侧滑关闭Activity及切换Activity的动画效果,主要介绍了SwipeBackActivity和SwipeBackLayout的实现原理。通过分析源码,讲解了SwipeBackActivityHelper的角色,以及SwipeBackLayout的构造、滑动监听、触摸事件处理、布局绘制等方面,提供了相关参考资料。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大屏幕时代的到来,目前大部分的APP都支持侧滑关闭Activity及切换Activity的动画效果,这些效果极大的提高了用户体验。比如苹果的safari中的滑动返回操作。
safari swipe back
这里写图片描述

我也参考了github上面的 ikew0ng/SwipeBackLayout项目写了一个自己的swipebacklayout。在源码的基础上,添加了一些注释,并没有对源码做出太大改动。
项目github地址:https://github.com/CameloeAnthony/SwipeBackActivity
下面对源码进行学习和分析:
(1)使用swipebackActivitity ,如图,只需要继承SwipeBackActivity,
这里写图片描述
并且注意在manifest文件中定义theme,添加如下属性:
这里写图片描述
(2)来看看swipeBackActivity是怎么实现的:


package nsu.edu.com.library;

import android.os.Bundle;

import android.support.v7.app.AppCompatActivity;
import android.view.View;

/**
 * all the subClass extends from this class to use swipe-back function
 */
public class SwipeBackActivity extends AppCompatActivity implements SwipeBackActivityBase {
   
    private SwipeBackActivityHelper mHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mHelper = new SwipeBackActivityHelper(this);
        mHelper.onActivityCreate();
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        mHelper.onPostCreate();
    }

    @Override
    public View findViewById(int id) {
        View v = super.findViewById(id);
        if (v == null && mHelper != null)
            return mHelper.findViewById(id);
        return v;
    }

    @Override
    public SwipeBackLayout getSwipeBackLayout() {
        return mHelper.getSwipeBackLayout();
    }

    @Override
    public void setSwipeBackEnable(boolean enable) {
        getSwipeBackLayout().setEnableGesture(enable);
    }

    @Override
    public void scrollToFinishActivity() {
        Utils.convertActivityToTranslucent(this);
        getSwipeBackLayout().scrollToFinishActivity();
    }
}

可以看到只需要对SwipeBackActivityBase 进行实现,其实主要的操作是由SwipeBackActivityHelper 的对象完成的。它主要完成了SwipeBackActivity在onCreate,onPostCreate,以及findViewById,都将操作传递给了SwipeBackActivityHelper 的对象。那么接下来看看它是怎么实现的。
(3)来看看SwipeBackActivityHelper 是怎么实现的。

package nsu.edu.com.library;

import android.app.Activity;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.view.LayoutInflater;
import android.view.View;


/**
 *
 */
public class SwipeBackActivityHelper {
   
    private Activity mActivity;

    private SwipeBackLayout mSwipeBackLayout;

    public SwipeBackActivityHelper(Activity activity) {
        mActivity = activity;
    }

    @SuppressWarnings("deprecation")
    public void onActivityCreate() {
        mActivity.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        mActivity.getWindow().getDecorView().setBackgroundDrawable(null);
        mSwipeBackLayout = (SwipeBackLayout) LayoutInflater.from(mActivity).inflate(
                R.layout.swipeback_layout, null);
        mSwipeBackLayout.addSwipeListener(new SwipeBackLayout.SwipeListener() {
            @Override
            public void onScrollStateChange(int state, float scrollPercent) {
            }

            @Override
            public void onEdgeTouch(int edgeFlag) {
                Utils.convertActivityToTranslucent(mActivity);
            }

            @Override
            public void onScrollOverThreshold() {

            }
        });
    }

    public void onPostCreate() {
        mSwipeBackLayout.attachToActivity(mActivity);
    }

    public View findViewById(int id) {
        if (mSwipeBackLayout != null) {
            return mSwipeBackLayout.findViewById(id);
        }
        return null;
    }

    public SwipeBackLayout getSwipeBackLayout() {
        return mSwipeBackLayout;
    }
}

其中进行的操作:
在activity调用onCreate之后会调用这的onActivityCreated,里面主要进行的操作是初始化SwipeBackLayout,并且将window的背景置为透明,然后设置SwipeBackLayout的滑动监听;
在activity的onPostCreate中也会调用这里的onPostCreate,将activity设置给SwipeBackLayout对象的attachToActivity;
findViewById方法也是将操作进一步传递给SwipeBackLayout的对象。
(4)下面就来看看SwipeBackLayout的实现,也是整个项目的重点:

package nsu.edu.com.library;

import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v4.view.ViewCompat;

import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import java.util.ArrayList;
import java.util.List;

public class SwipeBackLayout extends FrameLayout {
   
    /**
     * Minimum velocity that will be detected as a fling
     */
    private static final int MIN_FLING_VELOCITY = 400; // dips per second

    private static final int DEFAULT_SCRIM_COLOR = 0x99000000;

    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值