责任链模式在Android中的应用

*本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布

责任链其实在Android中出现的频率还蛮高的,事件传递就是一种责任链机制。接下来我为大家介绍在开发应用时责任链的用处:

  • 1.触摸事件的应用。
  • 2.响应事件的应用。

何为责任链?责任链说白了就是一个事件传递的链条,一般这个链条上有很多个事件消费者,每个事件消费者都有机会接收并消费事件:

第一个对象如果可以处理,则处理后返回,如果不能处理,则将事件传递下一个对象处理,以此推类。

那么它究竟在Android中有什么用呢,大伙可能知道,Android我们最为熟悉的就是Touch事件传递了,这就是一个典型的责任链模式。为了介绍的更直观一点,我简单画了一个界面:

上面的情况Android中有时候会遇到。有时界面上会弹出好几个这种临时显示的窗体或者控件,它们只是为了显示一下,然后需要用户关闭,常常我们希望可以按下返回键将它们关闭。

如果不使用责任链的话代码就会写成这个样子:

        if(A.isShow()){A.dismiss();}else if(B.isShow()){B.dismiss();}else if(C.isShow()){C.dismiss();}else if(D.isShow()){D.dismiss();}......

如果只有一两个,这么写也不会有什么错。但如果情况复杂了的话,这么写,设计上可就不妙了。所以这种情况极适合使用责任链模式来处理。

下面的例子以View的顺序隐藏、显示及View的动画演示了事件的传递:

例子中在按下事件分发的按钮时,控件会按照刚开始设置好的顺序依次隐藏、作动画、显示,最后再按下会关闭程序。

说一下实现:

先实现事件协定接口,这个接口用于相互之间的事件流转协议:

public interface IEvent<T> {public boolean onEvent(@NonNull T obj);
}

EventStub方法对IEvent接口进行了初步实现,它是事件传递的核心。它会首先询问自己是否消费事件,否则的话会交给下个消费者:

/*** 责任链抽象类,其中包含下一个实现者的应用*/
public abstract class EventStub<T> implements IEvent<T> {protected IEvent mEventStub;protected T viewStub;/*** @param mEventStub 下一级的事件接受者* @param viewStub   下一级被处理的对象*/public EventStub(IEvent mEventStub, T viewStub) {this.mEventStub = mEventStub;this.viewStub = viewStub;}@Overridepublic boolean onEvent(@NonNull T obj) {boolean b = onEventImpl(obj);if (!b && mEventStub != null)return mEventStub.onEvent(viewStub);return b;}/*** @param obj* @return 代表是否有消费事件*/protected abstract boolean onEventImpl(@NonNull T obj);
}

ViewEventStub是EventStub其中的一个实现,专门用于处理View的隐藏:

/*** View隐藏*/
public class ViewEventStub extends EventStub<View> {/*** @param mEventStub 下一级的事件接受者* @param viewStub   下一级被处理的对象*/public ViewEventStub(IEvent mEventStub, View viewStub) {super(mEventStub, viewStub);}@Overridepublic boolean onEventImpl(@NonNull View obj) {View tempView = obj;if (tempView.getVisibility() == View.VISIBLE) {tempView.setVisibility(View.INVISIBLE);return true;}return false;}
}

AnimationLeftEventStub也是EventStub的一个实现,用于使View做向左的动画:

public class AnimationLeftEventStub extends EventStub<View> {private boolean result = true;/*** @param mEventStub 下一级的事件接受者* @param viewStub   下一级被处理的对象*/public AnimationLeftEventStub(IEvent mEventStub, View viewStub) {super(mEventStub, viewStub);}@Overrideprotected boolean onEventImpl(@NonNull View obj) {if (result) {ObjectAnimator anim = ObjectAnimator.ofFloat(obj, "x", -400);anim.setDuration(1000);anim.addListener(new Animator.AnimatorListener() {@Overridepublic void onAnimationStart(Animator animation) {}@Overridepublic void onAnimationEnd(Animator animation) {result = false;}@Overridepublic void onAnimationCancel(Animator animation) {}@Overridepublic void onAnimationRepeat(Animator animation) {}});anim.start();}return result;}
}

AnimationRightEventStub与AnimationLeftEventStub同理,只是它是执行向右的动画,这里就不再贴代码了。

最后在CloseEventStub中也实现了EventStub,它用于处理最后一条消息的展示以及Activity的关闭:

    private class CloseEventStub extends EventStub<View> {/*** @param mEventStub 下一级的事件接受者* @param viewStub   下一级被处理的对象*/public CloseEventStub(IEvent mEventStub, View viewStub) {super(mEventStub, viewStub);}@Overrideprotected boolean onEventImpl(@NonNull View obj) {if (obj.getVisibility() == View.GONE) {obj.setVisibility(View.VISIBLE);return true;}if (!isDestroyed()) {finish();return true;}return false;}}

以上就是执行过程中的消费者,我们在Activity中将它们串起来:

        EventStub tempStub = new CloseEventStub(null, null);tempStub = new AnimationRightEventStub(tempStub, findViewById(R.id.view_7));tempStub = new AnimationLeftEventStub(tempStub, findViewById(R.id.view_6));tempStub = new ViewEventStub(tempStub, view_5);tempStub = new ViewEventStub(tempStub, view_4);tempStub = new ViewEventStub(tempStub, view_3);sourceStub = new ViewEventStub(tempStub, view_2);

然后由一个按钮触发点击事件,开始传递这个事件:

    /*** 外部触发回调** @param view*/public void dismiss(View view) {//将事件传给责任链头sourceStub.onEvent(view_1);}

好了,以上所有的关键步骤就完成了,接下来在点击dismiss方法的时候就会将每次的事件依次向下传递,它们会一个个的将事件消费,直至程序关闭。

完整的程序请参见:https://git.oschina.net/sahadev/Chain-of-Responsibility.git

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/479024.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

sklearn网格搜索找寻最优参数

大家好&#xff0c;在机器学习中&#xff0c;调参是一个非常重要的步骤&#xff0c;它可以帮助我们找到最优的模型参数&#xff0c;从而提高模型的性能。然而&#xff0c;手动调参是一项繁琐且耗时的工作&#xff0c;因此需要一种自动化的方法来搜索最佳参数组合。在这方面&…

最新版《神经网络和深度学习》中文版.pdf

获取最新版《神经网络和深度学习》最新版PDF和PPT的方法&#xff1a; 1.扫码关注 “Python与机器智能” 公众号2.后台回复关键词&#xff1a;神经网络注&#xff1a;此处建议复制&#xff0c;不然容易打错▲长按扫描关注&#xff0c;回复神经网络即可获取文档目录如下获取最新版…

一文盘点PaddlePaddle官方九大自然语言处理模型

一文盘点PaddlePaddle官方九大自然语言处理模型&#xff1a;百度paddlepaddle模型

论文浅尝 | 知识图谱的不确定性衡量

论文笔记整理&#xff1a;谭亦鸣&#xff0c;东南大学博士。来源&#xff1a;Knowledge and Information Systems volume 62, pages611–637(2020)链接&#xff1a;https://link.springer.com/article/10.1007/s10115-019-01363-0概要本文的核心工作是利用知识结构来衡量知识库…

LeetCode 709. 转换成小写字母

1. 题目 实现函数 ToLowerCase()&#xff0c;该函数接收一个字符串参数 str&#xff0c;并将该字符串中的大写字母转换成小写字母&#xff0c;之后返回新的字符串。 2. 解题 char tolower(char)小写比大写对应字符大32 class Solution { public:string toLowerCase(strin…

Logan:美团点评的开源移动端基础日志库

前言 Logan是美团点评集团移动端基础日志组件&#xff0c;这个名称是Log和An的组合&#xff0c;代表个体日志服务。同时Logan也是“金刚狼”大叔的名号&#xff0c;当然我们更希望这个产品能像金刚狼大叔一样犀利。 Logan已经稳定迭代了一年多的时间。目前美团点评绝大多数App已…

如何实现一个循环显示超长图片的控件

*本篇文章已授权微信公众号 guolin_blog &#xff08;郭霖&#xff09;独家发布 某次被问到如何实现一个滚筒状的控件&#xff0c;就是可以将一张很长的图片沿着Y轴无限旋转&#xff0c;如下图所示&#xff1a; 大概就是这个意思&#xff0c;当时还不知道图片可以裁剪&…

斯坦福大学——人工智能本科4年课程清单

文 | Mihail Eric编 | 大数据文摘相信每个入行人工智能的老手&#xff0c;对自己过往的几年学习生涯都或多或少会有一些遗憾&#xff1a;如果我当年先从基本概念入手就好了&#xff0c;如果我当年把核心算法吃的更透一点就好了……最近&#xff0c;一位在行业内工作了几年的斯坦…

bert模型简介、transformers中bert模型源码阅读、分类任务实战和难点总结

bert模型简介、transformers中bert模型源码阅读、分类任务实战和难点总结&#xff1a;https://blog.csdn.net/HUSTHY/article/details/105882989 目录 一、bert模型简介 bert与训练的流程&#xff1a; bert模型的输入 二、huggingface的bert源码浅析 bert提取文本词向量 BertMo…

LeetCode 476. 数字的补数(移位 异或^)

1. 题目 给定一个正整数&#xff0c;输出它的补数。补数是对该数的二进制表示取反。 2. 解题 先求出该数的2进制有多少位然后分别每位与1进行异或操作 class Solution { public:int findComplement(int num) {int n 1, num_copy num;while(num_copy/2){n;num_copy / 2;}wh…

论文浅尝 - ICLR 2020 | 用于文本推理的神经模块网络

论文笔记整理&#xff1a;邓淑敏&#xff0c;浙江大学在读博士&#xff0c;研究方向为低资源条件下知识图谱自动化构建关键技术研究。论文链接&#xff1a;https://openreview.net/pdf?idSygWvAVFPr Demo链接: https://demo.allennlp.org/reading-comprehension 代码链接: htt…

Android官方开发文档Training系列课程中文版:通知用户之构建通知

原文地址&#xff1a;http://android.xsoftlab.net/training/notify-user/index.html 引言 通知用于在有事件发生时&#xff0c;将事情以更便捷的方式展示给用户。用户可以在他们方便的时候直接与通知交互。 Notifications design guide课程讲述了如何设计有效的通知以及何时…

前端安全系列(二):如何防止CSRF攻击?

背景 随着互联网的高速发展&#xff0c;信息安全问题已经成为企业最为关注的焦点之一&#xff0c;而前端又是引发企业安全问题的高危据点。在移动互联网时代&#xff0c;前端人员除了传统的 XSS、CSRF 等安全问题之外&#xff0c;又时常遭遇网络劫持、非法调用 Hybrid API 等新…

全栈深度学习第3期: 怎样科学管理实验数据?

一起追剧鸭简介Berkeley全栈深度学习追剧计划是由夕小瑶的卖萌屋发起的优质公开课打卡项目&#xff0c;通过微信群为同期追剧的小伙伴提供交流平台。关于该计划的详请见这里。1. Berkeley深度学习追剧群目前已有1000小伙伴加入&#xff0c;公众号后台回复口令 深度学习追剧 入群…

PDFMiner:python 读取 pdf 内容

PDF的格式不是规范的&#xff0c;很多情况下没有逻辑结构&#xff0c;不能自适应页面大小的调整。PDFMiner是通过尝试猜测PDF的布局来重建其结构&#xff0c;有时候效果并不理想。 import importlib import sys import timeimportlib.reload(sys) time1 time.time()import os…

论文浅尝 - ICLR2020 | 通过神经逻辑归纳学习有效地解释

论文笔记整理&#xff1a;朱渝珊&#xff0c;浙江大学直博生。研究方向&#xff1a;知识图谱&#xff0c;快速表示学习等。论文链接&#xff1a;https://arxiv.org/pdf/1910.02481.pdf本文是ICLR 2020的一篇关于知识图谱中关于复杂&#xff08;树状、组合&#xff09;规则可微学…

Android官方开发文档Training系列课程中文版:通知用户之创建不同导航方式的Activity

原文地址&#xff1a;http://android.xsoftlab.net/training/notify-user/navigation.html 设计通知时要考虑到用户所预想的导航体验。通常有以下两种情况&#xff1a; 常规的Activity(Regular activity) 这里所启动的Activity是作为应用程序的正常流程部分出现的。 指定的…

上海交大张拳石:神经网络的变量交互可解释性研究

文 | Qs.Zhang张拳石知乎可解释性研究一直有两副嘴脸&#xff0c;一副烈火烹油繁花似锦&#xff0c;一副如履薄冰零丁洋里叹零丁。在2018年我开始发知乎是为了“活着”——被刷榜为王的风气屡屡打击之后&#xff0c;一朝中稿&#xff0c;倒过一口气来&#xff0c;终于可以跟大家…

基于TensorFlow Serving的深度学习在线预估

一、前言 随着深度学习在图像、语言、广告点击率预估等各个领域不断发展&#xff0c;很多团队开始探索深度学习技术在业务层面的实践与应用。而在广告CTR预估方面&#xff0c;新模型也是层出不穷&#xff1a; Wide and Deep[^1]、DeepCross Network[^2]、DeepFM[^3]、xDeepFM[^…

python库Camelot从pdf抽取表格数据以及python库camelot安装及使用中的一些注意事项

一、python库camelot安装及使用中的一些注意事项 1&#xff09;camelot方法有两种解析模式&#xff1a;流解析&#xff08;stream&#xff09;、格子解析&#xff08;lattice&#xff09;&#xff0c;其中格子解析能够保留表格完整的样式&#xff0c;对于复杂表格来说要优于流…