随手一写就是一个侧滑关闭activity

3607人阅读 评论(8) 收藏 举报
分类:

刚忙完一段时间,今天刚清闲会,就把以前写的东西整理整理。于是冥冥中发现有些东西完全可以共享出来,毕竟那么常见,而且简单实用。

实现原因

其实侧滑关闭activity在网上也有大量的文章去介绍他,我也有去看,要么是代码实在太多看不下去,要么就是跑了项目没有反应的。唯一的方法还是自己随手鲁一个~,侧滑这个东西在android中是比较少见的,ios是最常见不过了,因为毕竟他们没有物理返回键。还有UIScrollView那些。然而我们用的最多的QQ也只是有个功能,并没有真正的滑动效果。至于微信的,我记得N久以前滑出了一个bug。也没什么印象了。估计也是极小的概率事件。于是,当初我就强行的鲁了一个。下面我们一步步分析实现的思路以及代码。

百行代码解决侧滑关闭

首先来看下我们一些简单的定义:

private Activity activity;
    private Scroller scroller;
    //上次ACTION_MOVE时的X坐标
    private int last_X;
    //屏幕宽度
    private int width;
    //可滑动的最小X坐标,小于该坐标的滑动不处理
    private int min_X;
    // 页面边缘的阴影图
    private Drawable left_shodow;
    //页面边缘阴影的宽度默认值
    private static final int SHADOW_WIDTH = 16;
    // 页面边缘阴影的宽度
    private int shadow_width;
    // Activity finish标识符
    private boolean isFinish;

这边我已经注释过了,就不做过多就写了。接下来,我们看下我们的一些初始化已经外部调用方法:

  private void initView(Activity activity) {
        this.activity = activity;
        scroller = new Scroller(activity);
        left_shodow = getResources().getDrawable(R.drawable.left_shadow);
        int density = (int) activity.getResources().getDisplayMetrics().density;
        shadow_width = SHADOW_WIDTH * density;
        // 这里你一定要设置成透明背景,不然会影响你看到底层布局
        setBackgroundColor(Color.argb(0, 0, 0, 0));
    }

    public void bindActivity(Activity activity) {
        ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
        View child = decorView.getChildAt(0);
        decorView.removeView(child);
        addView(child);
        decorView.addView(this);

我们主要看下bindactivity这个方法。这个是我们用来绑定一个activity的。这个activity你们可以基于baseactivity实现一个backactivity。为什么要这么做,因为你每个activity都要写这么一句话,我感觉就是浪费时间,一个基类直接解决。这个activity我们可以这么写:

public abstract class SWBackActivity extends Activity {

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SWBackLayout layout = new SWBackLayout(this);
        layout.bindActivity(this);
    }

    protected abstract void afterInject();

    protected abstract void afterInitView();

}

那么接下来我们看下,如果对手势的处理让他侧滑关闭呢?


    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                last_X = (int) event.getX();
                width = getWidth();
                min_X = width / 10;
                break;
            case MotionEvent.ACTION_MOVE:
                int rightMovedX = last_X - (int) event.getX();
                if (getScrollX() + rightMovedX >= 0) {// 左侧即将滑出屏幕
                    scrollTo(0, 0);
                } else if ((int) event.getX() > min_X) {// 手指处于屏幕边缘时不处理滑动
                    scrollBy(rightMovedX, 0);
                }
                last_X = (int) event.getX();
                break;
            case MotionEvent.ACTION_UP:
                if (-getScrollX() < width / 3) {
                    scrollBack();
                    isFinish = false;
                } else {
                    scrollClose();
                    isFinish = true;
                }
                break;
        }
        return true;
    }

    private void scrollBack() {
        int startX = getScrollX();
        int dx = -getScrollX();
        scroller.startScroll(startX, 0, dx, 0, 300);
        invalidate();
    }

    private void scrollClose() {
        int startX = getScrollX();
        int dx = -getScrollX() - width;
        scroller.startScroll(startX, 0, dx, 0, 300);
        invalidate();
    }

    public void computeScroll() {
        if (scroller.computeScrollOffset()) {
            scrollTo(scroller.getCurrX(), 0);
            postInvalidate();
        } else if (isFinish) {
            activity.finish();
        }
        super.computeScroll();
    }

    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        drawShadow(canvas);
    }

    private void drawShadow(Canvas canvas) {
        // 保存画布当前的状态
        canvas.save();
        // 设置drawable的大小范围
        left_shodow.setBounds(0, 0, shadow_width, getHeight());
        // 让画布平移一定距离
        canvas.translate(-shadow_width, 0);
        // 绘制Drawable
        left_shodow.draw(canvas);
        // 恢复画布的状态
        canvas.restore();
    }

首先我们在ACTION_DOWN记录按下点的X坐标

然后在ACTION_MOVE中判断,如果我们getScrollX() + rightMovedX是否是大于0的,如果大于0,表示Activity处于滑动状态,并且是向左滑动,同时我们进行了判断,手指处于屏幕边缘时不可以滑动。

最后在ACTION_UP中判断如果手指滑动的距离大于布局宽度的1/3,表示将Activity滑出界面,否则滑动到起始位置,我们利用Scroller类的startScroll()方法设置好开始位置,滑动距离和时间,然后调用postInvalidate()刷新界面,之后就到computeScroll()方法中,我们利用scrollTo()方法对该布局的父布局进行滚动,滚动结束之后,我们判断界面是否滑出界面,如果是那就划出页面让activity finish掉。否则,布局就归位。

使用方法

其实使用方法很简单,直接继承SWBackActivity就可以了。那么我们最后来看下效果图:
这里写图片描述

查看评论

侧滑关闭activity之新特性SwipeBackActivity讲解

这是5.0以后的新特性(此功能好像在低版本有问题,5.0以上没有黑屏) 使用步骤如下: 1、导入SwipeBackActivity库 2、让当前activity继承于SwipeBackActiv...
  • professionIT
  • professionIT
  • 2016-07-12 16:31:09
  • 2186

仿微信的侧滑退出Activity

用苹果的小伙伴们都会知道,ios系统退出当前的页面只需要向右边侧滑,这是一个非常好的用户体验,但是Android官方并没有出具有这有性质的Activity,所以我们只能辛苦辛苦,自己动手写一个具有这种...
  • java_android_js
  • java_android_js
  • 2016-03-07 21:07:55
  • 2051

[android]手把手通过一个类实现侧滑退出activity功能

1、概述 *本文代码 非原创 来自于 一个 叫做NBAPlus的开源代码中.https://github.com/SilenceDut/NBAPlus 有兴趣的小伙伴们可以好好去了解下,推荐下,真™可...
  • qq_33456552
  • qq_33456552
  • 2016-07-08 15:13:01
  • 1055

一个简单的侧滑关闭Activity的示例

需求描述: 手指侧滑Activity,关闭之,等同于按下返回键。 实现原理: 在Activity的父类中重写setContentView方法,在其中统一添加一个父布局。来实现滑动的处理。 /** ...
  • baidu_28741289
  • baidu_28741289
  • 2016-01-25 17:26:08
  • 1180

三句话实现:Activity 侧滑退出,不信你来看看?

我的简书:三句话实现:Activity 侧滑退出,不信你来看看?现在很多应用都有左滑退出的功能,比如:微信 网上也好多例子,找到一种方法最小代价修改原来的代码,一般开发都会封装一个BaseActiv...
  • Imshuyuan
  • Imshuyuan
  • 2017-10-27 16:03:08
  • 213

android 侧滑消除activity框架

  • 2015年06月06日 21:26
  • 2.96MB
  • 下载

滑动关闭activity

  • 2014年09月20日 12:07
  • 6.1MB
  • 下载

用开源项目SwipBackLayout实现滑动关闭Activity

  • 2014年10月31日 14:54
  • 5.37MB
  • 下载

Android 向右滑动销毁(finish)Activity, 随着手势的滑动而滑动的效果

今天给大家带来一个向右滑动切换Activity的效果,Activtiy随着手指的移动而移动,该效果在Android应用中还是比较少见的,在IOS中就比较常见了,例如“网易新闻” ,"美食杰" , "淘...
  • xiaanming
  • xiaanming
  • 2014-03-13 09:19:34
  • 76847

SlidingPaneLayout实现Activity滑动返回

SlidingPaneLayout是V4包中新添加的组件,可以实现两列面板的切换。说先来看看API文档的说明: SlidingPaneLayout provides a horizontal, mu...
  • u014628886
  • u014628886
  • 2016-08-12 11:14:53
  • 416
    个人资料
    专栏达人 持之以恒
    等级:
    访问量: 18万+
    积分: 2050
    排名: 2万+
    我的公众号
    博客专栏