责任链模式在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,一经查实,立即删除!

相关文章

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

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

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

论文笔记整理&#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…

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

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

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

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

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

文 | 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;对于复杂表格来说要优于流…

LeetCode 561. 数组拆分 I

1. 题目 给定长度为 2n 的数组, 你的任务是将这些数分成 n 对, 例如 (a1, b1), (a2, b2), …, (an, bn) &#xff0c;使得从1 到 n 的 min(ai, bi) 总和最大。 示例 1:输入: [1,4,3,2]输出: 4 解释: n 等于 2, 最大总和为 4 min(1, 2) min(3, 4).来源&#xff1a;力扣&…

论文浅尝 - 计算机工程 | 知识图谱可视化查询技术综述

本文转载自公众号&#xff1a;计算机工程。知识图谱可视化查询技术综述王鑫, 傅强, 王林, 徐大为, 王昊奋知识图谱作为符号主义发展的产物&#xff0c;是人工智能技术和系统中的重要组成部分&#xff0c;其在百科知识、生物信息、社交网络以及网络安全等领域被广泛运用。知识图…

用VS Code直接浏览GitHub代码 | 12.1K星

文 | 金磊(发自凹非寺)源 | 量子位“看GitHub代码”这件事上&#xff0c;还在网页上点点点&#xff1f;用开发工具看代码&#xff0c;不香吗&#xff1f;于是&#xff0c;它来了&#xff0c;它来了——可以直接用VS Code方式打开GitHub代码的工具。而且在短短几天时间里&#x…

APPKIT打造稳定、灵活、高效的运营配置平台

一、背景 美团App、大众点评App都是重运营的应用。对于App里运营资源、基础配置&#xff0c;需要根据城市、版本、平台、渠道等不同的维度进行运营管理。如何在版本快速迭代过程中&#xff0c;保持运营资源能够被高效、稳定和灵活地配置&#xff0c;是我们团队面临的重大考验。…

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

原文地址&#xff1a;http://android.xsoftlab.net/training/notify-user/expanded.html#big-view 通知在通知栏中以两种风格呈现&#xff1a;正常视图与大视图。只有在通知展开的时候才会展示大视图。这只有在通知处于通知栏顶部时或者用户点击了通知时才会出现。 大视图于A…

论文浅尝-WSDM | Stepwise Reasoning for Multi-Relation QA

论文笔记整理&#xff1a;谭亦鸣&#xff0c;东南大学博士。来源&#xff1a;WSDM ’20链接&#xff1a;https://dl.acm.org/doi/pdf/10.1145/3336191.33718121.介绍知识图谱问答旨在利用知识图谱的结构化信息回答以自然语言提出的问题。当面对多关系问题时&#xff0c;现有基于…