浅谈Android 事件分发机制(二)

Android 事件分发机制详解/ 及Activity启动流程浅谈 目前网上的事件分发机制文章很多,可能大家看了很多,还是很懵逼,这篇文章是我自己总结的事件分发机制,提取了在事件分发机制中,最精华的部分,如果对事件分发还是不太清楚,可以看看这篇文章。 阅读详情

在上一篇文章中,浅谈Android 事件分发机制(一),简要分析了一下事件分发机制的原理,总结一下就是事件层层传递,直到被消费,原理看似简单,但是在实际使用过程中,场景各不相同,复杂程度也就因产品而异,这篇文章就通过给view加移动来模拟事件分发。

触摸事件

这里涉及到几个与手指触摸相关的常见事件:

坐标系对于单指触控移动来说,一次简单的交互流程是这样的:
手指落下(ACTION_DOWN) -> 移动(ACTION_MOVE) -> 离开(ACTION_UP)

注‘Android技术交流群878873098,欢迎大家加入交流,畅谈!本群有免费学习资料视频且免费分享

坐标系

Android坐标系以手机屏幕左上角的顶点为坐标原点,从该点向右为x轴正方向,从该点向下为y轴正方向。 上图所示,一次触摸涉及到多种距离的计算, 上图所标注的方法可以分为两类,一类是View提供的方法,一类是MotionEvent提供的方法。


View提供的:
getTop():获取到view自身的顶边到其父布局顶边的距离
getLeft():获取到view自身的左边到其父布局左边的距离
getRight():获取到view自身的右边到其父布局左边的距离
getBottom():获取到view自身底边到其父布局顶边的距离

MotionEvent提供的方法:
getX():获取触摸点距离控件左边的距离,即视图坐标
getY(): 获取触摸点距离控件顶边的距离,即视图坐标
getRawX():获取触摸点距离整个屏幕左边的距离,即绝对坐标
getRawY():获取触摸点距离整个屏幕顶边的距离,即绝对坐标
知道了以上的知识点后,基于文章一做view的移动,这里还是三个视图ViewC、ViewGroupB、ViewGroupA

C添加移动


给ViewC(蓝色区域)添加移动
onTouchEvent返回true,自身消费事件。
手指按下MotionEvent.ACTION_DOWN,记录当前距离控件左边和顶边的距离lastX、lastY。
手指移动时MotionEvent.ACTION_MOVE,获取当前距离控件左边和顶边的距离x、y,减去手指按下时记录的距离lastX、lastY,计算得到移动的距离,移动的距离加上view距离父布局的距离,得到相对于父布局的四个点坐标,layout重新确认位置。
手指离开MotionEvent.ACTION_UP,设置view距离父布局的margin,这边的操作主要是固定view的位置,后续和视图B一起移动时可固定位置。

private int lastX;
private int lastY;
@Override
public boolean onTouchEvent(MotionEvent event) {
    int x = (int) event.getX();
    int y = (int) event.getY();
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            lastX = x;
            lastY = y;
            break;
        case MotionEvent.ACTION_MOVE:
            //计算移动的距离
            int offsetX = x - lastX;
            int offsetY = y - lastY;
            int l = getLeft() + offsetX;
            int b = getBottom() + offsetY;
            int r = getRight() + offsetX;
            int t = getTop() + offsetY;
            //重新确认位置
            layout(l, t, r, b);
            break;
        case MotionEvent.ACTION_UP:
            LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) getLayoutParams();
            params.setMargins(getLeft(), getTop(), 0, 0);
            break;
        default:
            break;
    }
    return true;
}

B添加移动

同样给ViewGroupB添加以上的代码用于B的移动。(蓝色的视图C,黄色的视图B)
情况一:如上图 这里视图B、C的onTouchEvent都返回true,在C区域滑动,viewC消费了事件,不再传递给B;只有在B、C不重叠的区域滑动,C才会移动,这时没有接触到C,所以不会触发C的事件。因为我们在C的MotionEvent.ACTION_UP手指离开时固定了C到父布局(B)的距离,所以C相对B的位置没变。

情况二:如上图,将C的onTouchEvent返回false,在C区域滑动,事件没有消费,传递给到了B,B可以滑动,在不重叠区域一样可以滑动B。
如果B把事件拦截了onInterceptTouchEvent返回true,那么效果和情况二相同的,不管C的onTouchEvent返回啥,都响应不了。
这里模拟了视图B、C的滑动,A的话原理相同,这里就不再描述。
浅谈android事件分发的两篇文章结束了,这里只是简单描述模拟了事件分发。日常项目中若是遇到情况怕是更为复杂,想要彻底玩转事件分发机制还需要进一步的研究。

注‘Android技术交流群878873098,欢迎大家加入交流,畅谈!本群有免费学习资料视频且免费分享

保姆级教程:用Vue3+Element Plus快速搭建Flowable流程定义管理后台界面 本文提供了一份详细的Vue3+Element Plus教程,指导开发者快速搭建Flowable流程定义管理后台界面。从项目初始化、核心页面设计到响应式数据处理,全面覆盖前端开发关键步骤,帮助提升企业级应用开发效率。 阅读详情

相关推荐

前端开发学习--登录和注册页面设计(html和css,可完成两个页面点击切换)

今天学习了登录和注册页面的设计,主要是HTML和CSS部分,注册和切换采用了Js代码进行,后面将通过js进行填写内容的验证,进而可通过JSP跳转到Servlet进行DAO数据的校验,这属于后端部分了。 总体设计思路:整个页面设计可以分为主体(content)、头部(content-header)、内容(content-body)三个部分组成,其中是主体是根部,包含了头部和内容,头部和内容各自下设两...

weixin_43691879的博客 1万+

Android回顾---View事件体系

说到事件分发首先得说一下MotionEvent,MotionEvent代表了手指对屏幕的一系列操作,主要包括四个事件: ACTION_DOWN:手指触摸屏幕的瞬间触发 ACTION_MOVE:手指在屏幕上移动时触发 ACTION_UP:手指离开屏幕时触发 ACTION_CANCEL:这个是取消事件,非人为的。(如果我们把事件交给最底层的子View来消费,就会给父View(ViewGroup)设置一个不可拦截的flag,那么后续的事件父View默认都不会处理,但是不代表父View不能拦截了,如果此时父Vie

伊懿的博客 690

linux下使用Ollama本地部署LLM

Ollama 是一个用于在本地运行大语言模型(如 Llama 2、Mistral、Gemma、Qwen 等)的工具,支持模型的拉取、运行、管理等功能。当你运行ollama。

u013218342的博客 1659

android action up,Android多点触控:ACTION_UP并不总是被调用?

我开发了一个在视图中处理多点触控的Android应用程序.我基本上跟踪可能出现的几个MotionEvent,如ACTION_UP,ACTION_MOVE,…我在View类中覆盖的onTouch方法如下所示:public boolean onTouch(View view,MotionEvent event){int action = event.getAction() & MotionEv...

weixin_39861905的博客 604

【Cadence】 ADS Dynamic Link使用教程

在Cadence617上使用ADS Dynamic Link

乾巽的博客 6074

泰山派rk3566 audio音频基础介绍

本文介绍了嵌入式系统中音频处理的基础知识,重点围绕RK3566平台的音频子系统展开。文章首先解释了音频信号从模拟到数字的转换过程,包括采样率、位深和声道等核心概念。随后详细分析了嵌入式音频开发中的关键接口:I2C用于控制音频编解码器,I2S作为专用音频数据传输总线,以及PCM作为原始音频格式和ALSA设备抽象的双重含义。通过对这些基础概念和接口的解析,为在RK3566平台上进行音频驱动开发和应用调试提供了理论基础。

qq_37077309的博客 294

Android事件分发机制

Android事件分发机制

qq_27944153的博客 4012

Python爬虫实战:携程旅游攻略爬取全流程解析(动态接口+反爬破解+异步爬取)

本文介绍了携程旅游攻略的爬取全流程,涵盖静态和动态页面抓取、异步请求、高级反爬策略以及数据存储和简单分析。增加用户评论和评分抓取结合NLP分析攻略文本情感与关键词建立旅游推荐系统自动化代理IP池和验证码识别模块。

2201_76125261的博客 2039

android onTouch和手势基础详解

onTouch事件 做什么都好先了解原理以后的工作就会更简单,关于手势以及我们熟悉的onclick, onLongClick事件都是基于对onTouch事件的捕捉和处理。那么在使用手势工具类的前提下我们应该去学习了解基本的onTouch事件。onTouch常用的以下4个事件:1、ACTION_DOWN: 表示按下了屏幕,第一个执行也是必然执行的方法。2、ACTION_MOVE: 表示为移动手

食種之食物 2004

【教程4>第1章>第11节】使用MATLAB快速产生批量verilog语句加快FPGA开发

...........如果手动写,那么就非常麻烦,这个时候,我们借助matlab,则可以快速生成上述类型的verilog程序,我们编写如下的MATLAB语句。\n");\n");end。

FPGA/MATLAB学习教程/源码/项目合作开发 1239

飞牛fnNAS免费内网穿透之zerotier篇

本文介绍了如何通过ZeroTier实现飞牛NAS的远程文件共享。首先,用户需要在ZeroTier官网注册账号并创建虚拟局域网。接着,分别在Windows和飞牛NAS上安装ZeroTier客户端,并通过SSH登录飞牛NAS进行配置。安装完成后,用户可以在ZeroTier页面中授权设备加入虚拟局域网。最后,通过Windows的“网上邻居”功能访问飞牛NAS的共享文件夹,实现跨局域网的文件共享。这种方法不仅适用于文件共享,还可以用于打印机共享和远程桌面连接。

dgnankai的专栏 2464

Android事件分发机制浅谈(二)--源码分析(ViewGroup篇)

上节我们大致了解了事件分发机制的内容,大概流程,这一节来分析下事件分发的源代码。 我们先来分析ViewGroup中dispatchTouchEvent()中的源码 public boolean dispatchTouchEvent(MotionEvent ev){ if (actionMasked == MotionEvent.ACTION_DO...

dfzhxjcj66020的博客 173

第一章 EB安装

1.DemoWorkspace 是基于EB当前组件配置下的例程,包含了启动文件和中断服务函数以及组件demo。2.Mclsar 下存放的是EB的插件包和静态MCAL的驱动文件。

舊梦的博客 1955

Android——浅谈事件分发机制

A flexible view for providing a limited window into a large data set.

WormholeStack 4180

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

浅谈Android事件分发机制

在Android实际开发过程中经常会遇到View之间的滑动冲突,如ScrollView与Listview、RecyclerView之间的嵌套使用。在很好的解决此类问题之前,我们应深入的了解Android事件响应机制。

张许平的博客 1万+

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Android事件分发机制详解

从浅入深分析事件分发。

zjm807778317的博客 2653

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

浅谈android事件分发机制

浅谈android事件分发机制 最近准备换项目,因此需要重新回顾一下一些知识点,其中就包含事件分发机制, 先说说什么是事件分发机制,简单点说事件分发机制就是“将点击事件(MotionEvent)传递到某个具体的View& 处理的整个过程“,注意”过程“这俩个字 看别人的再多东西,不如自己上手来一遍,写个简单的demo然后我们来学习下事件分发机制。以下是代码准备 import android.os.Bundle; import android.util.Log; import androi.

liulong_的博客 350

浅谈android中View的事件分发机制

Android事件分发机制是Android开发者必须了解的知识,这方面的内容很多,自己纯看文章总觉得比较抽象,自己写了个demo,理一下事件分发的流程,加深印象。 view结构 PhoneWindow 的指示通过 DecorView 传递给下面的 View,下面 View 的信息也通过 DecorView 回传给 PhoneWindow。这里我们主要聊聊ViewGroup与view的事件分发 ...

baidu_32015283的博客 298

Android事件分发浅谈

Android事件分发机制浅谈 前言:可能Android的事件分发对于刚学Android的童鞋来说接触得不多,这样不奇怪。因为刚学的时候,一般人很难注意到或是会选择主动去了解。那么究竟什么是Android的事件分发呢? 或许刚说出来,有点觉悟的新手会想到就是那些按钮的点击事件、或是说监听。而这些也确实是Android事件分发的其中一部分。由于Android的事件分发其实

u011070603的博客 1437

Android事件分发机制,浅谈解析

通过简单的demo来解析事件分发机制,主要通过简单的三层Activity–>ViewGrop–>View来分析事件分发机制。先通过一张简单的事件分发流程图来看看事件分发的基本流程。 Activity与View是没有onInterceptTouchEvent这个方法的,也就是说这两者没法使用该方法拦截事件,我们先按照上面流程图来建一个demo,看看事件分发是否与我们流程图所画的一样。如...

后知后觉者! 455

浅谈Android中的事件分发

在我们实际的项目中,涉及到手势的操作很多,这就需要我们对Android的事件有一定的了解,才能设计出好的手势。本文就对Android中的事件分发做一些简单的介绍。 1、Android中事件的基本概念 1.1、事件分发的对象 事件分发的对象就是事件,当我们触摸屏幕的时候就会触发一系列的事件。 Touch事件相关细节(发生触摸的位置、时间、历史记录、手势动作等)被封装成MotionEvent对象。 1.2、事件的种类 Android中的事件分为4类: MotionEvent.ACTION_DOWN:按下Vie

HughZhao的博客 592

浅谈View的事件分发机制

View的事件分发是指对于屏幕的Touch事件的分发。 首先,当在屏幕上进行操作的时候,会触发一系列的touch事件,系统会将其封成 MotionEvent,然后向下分发给各个View,寻找事件的处理者。 过程:首先,事件会从顶层的ViewGroup逐渐向下传递(在这个过程中判断是否拦截,若拦截则不再向下传递而是直接开始处理),然后又从底层View再向上传递(在这个过程中开始处理事件,若是处理的话...

zip_tts的博客 339

浅谈Android事件分发——ViewGroup里的事件分发

文章目录浅谈ViewGroup里的事件分发2.ViewGroup内的事件分发2.1 确定几条规则2.2 Handle initial down2.2 Check for interception2.3 Update pointer down touch targets list2.4 Dispatch to targets2.5 Update point up or cancel tarch targets list 浅谈ViewGroup里的事件分发 为啥一上来就是标号2?因为我太懒了,目标是分析Act.

qq_42898299的博客 311
上一篇: 浅谈Android 事件分发机制(一)
下一篇: 别再抱怨了,国内这么多优秀的Android资源你都知道吗?
北辰丶
博客等级 码龄8年 67粉丝 197原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值