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

实现原因

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

百行代码解决侧滑关闭

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

  1. private Activity activity;
  2. private Scroller scroller;
  3. //上次ACTION_MOVE时的X坐标
  4. private int last_X;
  5. //屏幕宽度
  6. private int width;
  7. //可滑动的最小X坐标,小于该坐标的滑动不处理
  8. private int min_X;
  9. // 页面边缘的阴影图
  10. private Drawable left_shodow;
  11. //页面边缘阴影的宽度默认值
  12. private static final int SHADOW_WIDTH = 16;
  13. // 页面边缘阴影的宽度
  14. private int shadow_width;
  15. // Activity finish标识符
  16. private boolean isFinish;

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

  1. private void initView(Activity activity) {
  2. this.activity = activity;
  3. scroller = new Scroller(activity);
  4. left_shodow = getResources().getDrawable(R.drawable.left_shadow);
  5. int density = (int) activity.getResources().getDisplayMetrics().density;
  6. shadow_width = SHADOW_WIDTH * density;
  7. // 这里你一定要设置成透明背景,不然会影响你看到底层布局
  8. setBackgroundColor(Color.argb(0, 0, 0, 0));
  9. }
  10. public void bindActivity(Activity activity) {
  11. ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
  12. View child = decorView.getChildAt(0);
  13. decorView.removeView(child);
  14. addView(child);
  15. decorView.addView(this);

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

  1. public abstract class SWBackActivity extends Activity {
  2. protected void onCreate(Bundle savedInstanceState) {
  3. super.onCreate(savedInstanceState);
  4. SWBackLayout layout = new SWBackLayout(this);
  5. layout.bindActivity(this);
  6. }
  7. protected abstract void afterInject();
  8. protected abstract void afterInitView();
  9. }

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

  1. public boolean onTouchEvent(MotionEvent event) {
  2. switch (event.getAction()) {
  3. case MotionEvent.ACTION_DOWN:
  4. last_X = (int) event.getX();
  5. width = getWidth();
  6. min_X = width / 10;
  7. break;
  8. case MotionEvent.ACTION_MOVE:
  9. int rightMovedX = last_X - (int) event.getX();
  10. if (getScrollX() + rightMovedX >= 0) {// 左侧即将滑出屏幕
  11. scrollTo(0, 0);
  12. } else if ((int) event.getX() > min_X) {// 手指处于屏幕边缘时不处理滑动
  13. scrollBy(rightMovedX, 0);
  14. }
  15. last_X = (int) event.getX();
  16. break;
  17. case MotionEvent.ACTION_UP:
  18. if (-getScrollX() < width / 3) {
  19. scrollBack();
  20. isFinish = false;
  21. } else {
  22. scrollClose();
  23. isFinish = true;
  24. }
  25. break;
  26. }
  27. return true;
  28. }
  29. private void scrollBack() {
  30. int startX = getScrollX();
  31. int dx = -getScrollX();
  32. scroller.startScroll(startX, 0, dx, 0, 300);
  33. invalidate();
  34. }
  35. private void scrollClose() {
  36. int startX = getScrollX();
  37. int dx = -getScrollX() - width;
  38. scroller.startScroll(startX, 0, dx, 0, 300);
  39. invalidate();
  40. }
  41. public void computeScroll() {
  42. if (scroller.computeScrollOffset()) {
  43. scrollTo(scroller.getCurrX(), 0);
  44. postInvalidate();
  45. } else if (isFinish) {
  46. activity.finish();
  47. }
  48. super.computeScroll();
  49. }
  50. protected void dispatchDraw(Canvas canvas) {
  51. super.dispatchDraw(canvas);
  52. drawShadow(canvas);
  53. }
  54. private void drawShadow(Canvas canvas) {
  55. // 保存画布当前的状态
  56. canvas.save();
  57. // 设置drawable的大小范围
  58. left_shodow.setBounds(0, 0, shadow_width, getHeight());
  59. // 让画布平移一定距离
  60. canvas.translate(-shadow_width, 0);
  61. // 绘制Drawable
  62. left_shodow.draw(canvas);
  63. // 恢复画布的状态
  64. canvas.restore();
  65. }

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

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

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

使用方法

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

随手一写就是一个侧滑关闭activity的更多相关文章

  1. 分分钟教你集成沉浸式侧滑关闭Activity

    网上搜索侧滑关闭Activity,几乎没有系统状态栏跟随页面一起联动的,有明显的撕裂感,而这里则是状态栏跟随页面联动的,说来集成也是简单,等会你就知道了. 个人习惯,写博客前喜欢先截图 1.首先以项目 ...

  2. 侧滑关闭Activity的解决方案——SwipeBackLayout

    项目地址:ikew0ng/SwipeBackLayout: An Android library that help you to build app with swipe back gesture. ...

  3. 【android】侧滑关闭activity

    最近在使用IOS系统的时候,发现侧滑关闭很实用,因为单手就可以操作,不需要点击左上角的回退按钮.或者返回键了. 所以打算在android上实现这个技术. 需求: 1:IOS只能在屏幕边缘开始,往中间进 ...

  4. 【java基础】随手写的一个日期计算,新手可以看看

    随手写的一个例子, 只是练习下自己的代码布局以及思路.. 1. 先写下简单的测试 2. 根据常用的不用修改的变量抽取出来, 作为常量(常量的命名可能有点不规范,谅解~) 3. 方法的作用不一样, 抽取 ...

  5. sql server 关于表中只增标识问题 C# 实现自动化打开和关闭可执行文件(或 关闭停止与系统交互的可执行文件) ajaxfileupload插件上传图片功能,用MVC和aspx做后台各写了一个案例 将小写阿拉伯数字转换成大写的汉字, C# WinForm 中英文实现, 国际化实现的简单方法 ASP.NET Core 2 学习笔记(六)ASP.NET Core 2 学习笔记(三)

    sql server 关于表中只增标识问题   由于我们系统时间用的过长,数据量大,设计是采用自增ID 我们插入数据的时候把ID也写进去,我们可以采用 关闭和开启自增标识 没有关闭的时候 ,提示一下错 ...

  6. Activity详解一 配置、启动和关闭activity

    先看效果图: Android为我们提供了四种应组件,分别为Activity.Service.Broadcast receivers和Content providers,这些组建也就是我们开发一个And ...

  7. Activity详解一 配置、启动和关闭activity转载 https://www.cnblogs.com/androidWuYou/p/5887726.html

    先看效果图: Android为我们提供了四种应组件,分别为Activity.Service.Broadcast receivers和Content providers,这些组建也就是我们开发一个And ...

  8. 自己写的一个SqlHelper,感觉使用起来挺方便的

    自己写的一个SqlHelper,感觉使用起来挺方便的 using System; using System.Data; using System.Collections.Generic; using ...

  9. 用c#写的一个局域网聊天客户端 类似小飞鸽

    用c#写的一个局域网聊天客户端 类似小飞鸽 摘自: http://www.cnblogs.com/yyl8781697/archive/2012/12/07/csharp-socket-udp.htm ...

随机推荐

  1. cogs 539. 牛棚的灯

    ★★☆   输入文件:lights.in   输出文件:lights.out   简单对比 时间限制:1 s   内存限制:128 MB [问题描述] 贝希和她的闺密们在她们的牛棚中玩游戏.但是天不从 ...

  2. RMI远程方法调用

    RMI远程方法调用:适用于 客户端 调用 服务器 内的方法:(Kotlin 语言编写) 如果业务为二个服务器之间的通信,还是得用消息队列的形式,因为RMI 不适合 双向 调用 下面介绍RMI 的使用方 ...

  3. DOS/BAT批处理if exist else 语句的几种用法

    在DOS批处理命令中常常会通过if语句来进行判断来执行下面的命令, 那么批处理if语句怎么用呢,下面学无忧小编就来说说有关批处理if以及if exist else语句的相关内容.一.批处理if书写格式 ...

  4. 5.scala中的对象

    排版乱?请移步原文获得更好的阅读体验 1.单例对象 scala中没有静态类或者静态方法,都是通过object实现的,它表示某个类的单例对象.如object People是class People的单例 ...

  5. git-svn — 让git和svn协同工作

     git-svn — 让git和svn协同工作 svn作为一个优秀源码版本的管理工具,可以适合绝大多数项目.但是因为它的采用中心化管理,不可避免的存在本地代码的备份和版本管理问题.也就是说对于尚未或暂 ...

  6. Python基础笔记系列十四:python无缝调用c程序

    本系列教程供个人学习笔记使用,如果您要浏览可能需要其它编程语言基础(如C语言),why?因为我写得烂啊,只有我自己看得懂!! python语言可以对c程序代码进行调用,以弥补python语言低性能的缺 ...

  7. 51nod 1187 寻找分数

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  8. 新浪云连接数据库php

    一般数据库连接$con = mysql_connect("localhost", "root", ""); 而新浪云共享数据库 <?p ...

  9. js模糊查询

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. Python 使用sys模块

      你已经学习了如何在你的程序中定义一次函数而重用代码.如果你想要在其他程序中重用很多函数,那么你该如何编写程序呢?你可能已经猜到了,答案是使用模块.模块基本上就是一个包含了所有你定义的函数和变量的文 ...