View的事件分发机制
(一)为什么要有事件分发机制
安卓界面上面的View的层级结构是树形的,可能出现多个View重叠在一起的现象(如下图),当我们点击的地方为多个View重叠的区域时,这个点击事件应该给谁呢?为了解决这一个问题,就有了事件分发机制。
(二)Android界面上的View层级结构
例如我们当前界面的xml布局文件如下:
<RootViewGroup xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools" android:id="@+id/root_view_group"android:layout_width="match_parent" android:layout_height="match_parent"tools:context="com.yl.MainActivity"><ViewGroup2android:id="@+id/view_group1"android:layout_width="200dp"android:layout_height="200dp"><Viewandroid:id="@+id/view4"android:layout_width="50dp"android:layout_height="50dp"></View><Viewandroid:id="@+id/view5"android:layout_width="50dp"android:layout_height="50dp"></View></ViewGroup2><Viewandroid:id="@+id/view2"android:layout_width="50dp"android:layout_height="50dp"></View><Viewandroid:id="@+id/view3"android:layout_width="50dp"android:layout_height="50dp"></View>
</RootViewGroup>
在 Android一个界面中 最顶层的容器是Window,但Window是抽象的,其唯一的实现类是PhoneWindow,但其实PhoneWindow只是一个抽象的概念,其内部类DecorView,才是实际承载View的容器,故而此界面的View的层级结构大致如下:
正是View的树形层级结构,决定了它能够实现事件分发机制,有序地分发事件。
(三)事件分发机制的原理
在(一)中我们已经大致了解了View的层级结构,由于Window、PhoneWindow、DecorView较为底层且抽象,故而我们下面讨论的事件分发流程,会省略对Window、PhoneWindow和DecorView的描述,直接到RootViewGroup往下进行描述,原理都是一样的。
1.总体的流程
首先捋一下大大的总体流程,假设我们当前MainActivity的xml布局如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main"android:layout_width="match_parent" android:layout_height="match_parent"tools:context="com.yl.MainActivity"><Viewandroid:id="@+id/view1"android:background="#E4A07B"android:layout_width="200dp"android:layout_height="200dp"/>
</RelativeLayout>
当我们点击MainActivity的界面上的View1时,事件的分发流程如下:
MainActivity->RelativeLayout->View1(正确√)
可见是自顶向下的传递的,MainActivity先接收到事件,而后是RelativeLayout(RootViewGroup),最后才是View。
和我们传统的思维是截然相反的...我们传统的思维,是从点击处向外扩散(至少我是这样想的...),即
View1->RelativeLayout->MainActivity(大大滴错误×××)
这也是我曾经的想法,从我的角度来说我为什么会有这个思维呢?
因为我当时并没有真正理解View的事件分发机制,平时使用时,同时对ViewGroup和其内部包含的子View设置点击事件,点击事件总会被子View响应,ViewGroup总是不响应,所以惯性思维的觉得事件是从子View发出,逐层向上传递的...。
如果你也有与我曾经一样的疑惑,就接着看吧~ //TODO::问题1
2. 具体的流程
首先我们需要了解关于View事件分发机制的三个非常重要的方法:
从上图可以看到,
-
ViewGroup拥有三个方法,很容易理解,因为ViewGroup内部可以包含多个子View嘛,所以需要有dispatchTouchEvent方法将事件分发给子View;需要有onInterceptTouchEvent方法来拦截事件不让子View接收;也需要onTouchEvent方法来消费事件使事件不再向上回传处理。
-
Activity只有两个方法,没有事件拦截方法,这是因为事件最开始的接受者就是Activity,如果拦截了下面的View就接收不到事件了,这样做是没有意义的。
-
View也只有两个方法,没有事件拦截方法,这是因为View是最底层的事件接受者,它的下面没有子View,也就没有拦截的必要的,但View为什么会有事件分发的方法呢,它又没有子View,留着这个疑问,我们接着向下看。//TODO::问题2
这三个方法的返回值都是Boolean,通过返回 true 和 false 来控制事件传递的流程。
根据这三个方法我们再来捋一下上面那个例子的事件分发流程:
-
Activity最先接收到事件,首先调用到自身
dispatchTouchEvent
方法,而后在dispatchTouchEvent
方法中经过一系列调用最终调用到RootViewGroup的dispatchTouchEvent
方法实现事件分发。 -
RootViewGroup的
dispatchTouchEvent
方法被调用,在RootViewGroup的dispatchTouchEvent
方法调用onInterceptTouchEvent
方法判断是否拦截事件 -
若
onInterceptTouchEvent
方法返回true,代表RootViewGroup拦截事件,不继续调用子View的dispatchTouchEvent
方法向下分发事件,而是调用onTouchEvent()
自己处理事件,不一定消费,onTouchEvent()
返回true才是消费,onTouchEvent()
返回false则继续向上回传,直至事件被消费或到达最顶层任然没有被处理最终丢弃。(onInterceptTouchEvent
方法返回true,事件从此处不再继续向下分发传递) -
若
onInterceptTouchEvent
方法返回false,代表RootViewGroup不拦截事件,继续调用子View的dispatchTouchEvent
方法实现事件分发。(onInterceptTouchEvent
方法返回false,事件继续向下分发传递) -
View1的
dispatchTouchEvent
方法被调用,由于View1下面没有子View了,故而,直接在dispatchTouchEvent
方法中调用onTouchEvent
方法处理事件,若onTouchEvent
方法返回true则事件被消费,若返回false则事件继续向上回传,直至事件被消费或到达最顶层任然没有被处理最终丢弃。
好了,捋完了,是不是对事件分发流程又清晰一点了~
如果你熟悉设计模式,你就会发现,这其实是一个很经典的责任链模式,每个类都对事件进行自己的处理(拦截、分发、消费),而后再向下传递处理。
下面来了解一下这三个重要的方法都各自做了什么,是怎么调用实现事件分发的。
-
dispatchTouchEvent
方法:负责分发事件View的
dispatchTouchEvent
方法:主要用于调度onTouchListener注册的触摸事件和onTouchEvent方法,将事件分发给事件监听器,并获取事件监听器的消费结果。//简化代码逻辑大致如下:(以下只是代码的关键逻辑代码,帮助我们理解大体的流程,不要太扣细节哈) public boolean dispatchTouchEvent(MotionEvent event){//注册了触摸监听器,判断触摸监听器是否返回trueif(mOnTouchListener.onTouch(this,event)){//事件被消费return true;}//注册了触摸监听器但触摸监听器并未返回true 或 未注册触摸监听器,调用onTouchEvent方法将事件分发给其他监听器处理else if(onTouchEvent(event)){//有其他监听器处理了事件,事件被消费return true;}//没有任何监听器被注册,事件没有被消费return false; }
到此处你是否已经领悟了我们上面的 问题2 了呢?
View虽然没有子View可以分发事件,但是还有事件监听器啊,所以view需要
dispatchTouchEvent
方法来分发事件给已注册的事件监听器。ViewGroup 的
dispatchTouchEvent
方法:主要用于判断是否拦截,如不拦截则调度子View的dispatchTouchEvent方法,将事件分发给子View;若拦截则调用自身的onTouchEvent方法,将事件分发给自身的事件监听器,并获取事件监听器的消费结果。//简化后代码主体逻辑大致如下: public boolean dispatchTouchEvent(MotionEvent event){boolean result = false;//调用onInterceptTouchEvent方法判断自身是否拦截事件if(!onInterceptTouchEvent(event)){//不拦截,继续向下分发事件//从 后往前 遍历所有子View,并判断点击位置坐标与子View的区域,以确定被点击的子View,将事件分配给该子View//如果点击的位置是多个子View重叠的位置怎么办呢?//答案是:会将事件分发给 可点击的 显示在最上面的子View!//(注意此处说的是可点击的!若View2盖在了view1上面,但view2不可点击,view1可点击,事件还是会分发给view1的!)//因为后添加的子View覆盖在之前的View上方,而我们是从后往前遍历的,//所以最终会将事件分发给重叠位置显示在最上面的子View//故而最终事件只会被分发给 一个子View 进行处理,并不是群发!result = child.dispatchTouchEvent(event);//将事件分配给匹配的子View并获取其消费结果}//走到此处有两种情况://1.事件被拦截//2.事件没有被拦截但子View并没有消费事件,事件继续回传给ViewGroup处理if(!result){//调用自身的onTouchEvent(event)处理事件并获取消费结果result = onTouchEvent(event);}return result; }
-
onInterceptTouchEvent
方法:判断是否拦截事件由于
onInterceptTouchEvent
方法只有ViewGroup拥有,故只分析ViewGroup//这个就是源码咯,一模一样的 public boolean onInterceptTouchEvent(MotionEvent event){if (ev.isFromSource(InputDevice.SOURCE_MOUSE)&& ev.getAction() == MotionEvent.ACTION_DOWN&& ev.isButtonPressed(MotionEvent.BUTTON_PRIMARY)&& isOnScrollbarThumb(ev.getX(), ev.getY())) {return true;//特殊情况:这个事件是拖动滚动条时,事件应该被ViewGroup拦截}return false;//默认不拦截 } //若要拦截可以重写此方法,并覆盖返回值 //当事件被拦截时,会发送一个ACTION_CANCEL事件给子View,表示事件取消,后续事件不会再传递过去。
-
onTouchEvent()
方法:将事件分发给事件监听器并返回事件监听器的消费结果事件最终都是分发给View中注册的事件监听器的
//简化后代码主体逻辑大致如下: public boolean onTouchEvent(MotionEvent event){...int action = event.getAction();...//判断View是否可点击if (((viewFlags & CLICKABLE) == CLICKABLE ||(viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) ||(viewFlags & CONTEXT_CLICKABLE) == CONTEXT_CLICKABLE) {//可点击//判断事件类型并分发给对应的监听器switch (action) {case MotionEvent.ACTION_UP://移除长按//检测单击事件...break;case MotionEvent.ACTION_DOWN://检测长按事件...break;case MotionEvent.ACTION_CANCEL:...break;case MotionEvent.ACTION_MOVE:...break; }return true;//在if中,故只要view 可点击 事件就会被消费!!!}return false;//事件没有被消费,继续向上回传 }
补充:如何使一个view可点击?
-
在xml文件中为一个view指定
android:clickable="true"
-
为view注册OnClickListener
、
OnLongClickListener、
onContextClickListener`其中的一个 -
此外,Android中一些控件(如Button、CheckBox)默认就是可点击的
注意:我们上面并没有提到
OnTouchListener
,因为 为View注册OnTouchListener
并 不会影响 View的可点击状态!但为View注册
OnTouchListener
并返回true还是会消费事件的,原因请看View的dispatchTouchEvent
方法。到此处,我们已经分析完事件分发机制中三个重要的方法了,来解答一下之前留下的 问题1
当我们同时给ViewGroup和其内部的子View注册点击事件监听器OnClickListener时,为什么用户点击后,总是 子View消费事件,而ViewGroup无法消费事件?(此处我们假设,此ViewGroup就是根ViewGroup,且ViewGroup没有重写
onInterceptTouchEvent
方法并返回true去拦截事件)看一下事件分发流程:
-
Activity接收到事件,调用
dispatchTouchEvent
方法,经过一系列的调用PhoneWindow->DecorView->调用到ViewGroup的dispatchTouchEvent
方法,将事件分发给ViewGroup -
在ViewGroup的
dispatchTouchEvent
方法中,先是调用了onInterceptTouchEvent
方法判断ViewGroup是否拦截事件 -
此处我们的问题是默认情况没有重写拦截方法的,故而不拦截,故而会直接调用到ViewGroup子View的
dispatchTouchEvent
方法 -
而此时子View注册了点击监听器OnClickListener,故而为可点击状态,子View的
dispatchTouchEvent
方法会直接返回true,消费了事件。 -
此时再回到ViewGroup的
dispatchTouchEvent
方法中,由于返回值已被赋值为子View的返回值结果true,故不会调用到自身的onTouchEvent()
方法,故而ViewGroup也就无法消费事件了。
-
参考文章:
安卓自定义View进阶-事件分发机制原理
安卓自定义View进阶-事件分发机制详解
相关文章:
View的事件分发机制
(一)为什么要有事件分发机制 安卓界面上面的View的层级结构是树形的,可能出现多个View重叠在一起的现象(如下图),当我们点击的地方为多个View重叠的区域时,这个点击事件应该给谁呢?为…...
【C++】类和对象【下】
目录 一、再探构造函数1、测试题 二、类型转换三、static成员1. 静态成员变量2. 静态成员函数 四、友元五、内部类六、匿名对象七、对象拷贝时的编译器优化 个人主页<—请点击 C专栏<—请点击 一、再探构造函数 之前我们实现构造函数时,初始化成员变量主要使…...
【JS逆向基础】并发爬虫
前言:所谓并发编程是指在一台处理器上“同时”处理多个任务。并发是在同一实体上的多个事件。强调多个事件在同一时间间隔发生。 1,进程、线程以及协程 【1】进程概念 我们都知道计算机的核心是CPU,它承担了所有的计算任务;而操作系统是计算…...
Android组件化 -> 基础组件进行Application,Activity生命周期分发
在lib_common基础组件模块创建上下文持有类,生命周期派发类 object AppContextProvider {private lateinit var application: Applicationprivate var currentActivityRef: WeakReference<Activity>? null// 应用生命周期监听器列表private val appLifecyc…...
42. PCB防静电环设计
PCB防静电环的作用 1. PCB防静电环的作用2. 防静电环设计技术点 1. PCB防静电环的作用 防静电环主要用于生产、运输、售后等环节人体会直接接触电路板的场景。 防静电环只在顶层和底层设计即可。 2. 防静电环设计技术点...
深入理解Java反射机制
java反射是java语言中一个强大而灵活的特性,它允许程序在运行时检查和操作类、接口、字段和方法。 为了方便理解下文,我先给出Cat对象 public class Cat implements jump,Run {private int age;public String name;protected String color;double he…...
嵌入式音视频通话EasyRTC基于WebRTC技术驱动智能带屏音箱:开启智能交互新体验
一、引言 随着智能家居市场的蓬勃发展,智能带屏音箱作为家庭智能交互中心的重要组成部分,其功能需求日益丰富。EasyRTC凭借其低延迟、高稳定性的特点,为智能带屏音箱带来了全新的交互体验,能满足用户在视频通话、远程监控、在线…...
1987-2023年各省进出口总额数据整理(含进口和出口)(无缺失)
1987-2023年各省进出口总额数据整理(含进口和出口)(无缺失) 1、时间:1987-2023年 2、来源:各省年鉴、统计公报 3、指标:进出口总额(万美元)、进口总额(万美…...
paddle ocr 或 rapid ocr umi ocr 只识别了图片的下部分内容 解决方案
如上图,识别的准确率其实很高,但是只识别了下半部分的内容,上半部分的内容就没有识别到,其实是程序设置有点问题,程序设置的解决方案如下: 如上图,识别的准确率其实很高,但是只识别了下半部分的内容,上半部分的内容就没有识别到,其实是程序设置有点问题,程序设置的…...
【深度学习-Day 7】精通Pandas:从Series、DataFrame入门到数据清洗实战
Langchain系列文章目录 01-玩转LangChain:从模型调用到Prompt模板与输出解析的完整指南 02-玩转 LangChain Memory 模块:四种记忆类型详解及应用场景全覆盖 03-全面掌握 LangChain:从核心链条构建到动态任务分配的实战指南 04-玩转 LangChai…...
如何测试 esp-webrtc-solution_solutions_doorbell_demo 例程?
软件准备 esp-webrtc-solution/solutions/doorbell_demo 例程 此例程集成了 WebSocket 传输视频流的应用 硬件准备 ESP32P4-Function-Ev-Board 环境搭建 推荐基于 esp-idf v5.4.1 版本的环境来编译此例程 若编译时出现依赖的组件报错,可进行如下修改ÿ…...
default和delete final和override
1.default和delete default 1.生成默认成员函数 2.仅适用于特殊成员函数(如构造函数、析构函数、拷贝/移动操作等) delete 1.删除函数 2.可应用于任何函数(不限于特殊成员函数) 2.final 和override final 用于类:…...
Nvidia Orin 安装onnxruntime-gpu
在用英伟达边缘设备Nvidia Orin 安装onnxruntime-gpu环境时, 通常会遇到很多问题。 在正常的Nvidia 服务器上安装onnxruntime-gpu 是非常简单的, 直接pip install onnxruntime-gpu即可, 但是在边缘设备上就没有这么简单了。 直接pip install…...
C++ CRTP技术(奇异递归模版模式)
C 的CRTP技术 最近了解到C的CRTP技术,通过博客来这里记录一下。 我们首先可以了解一下什么是CRTP技术。CRTP是C的一种高级模版变成模式。 他主要的用途有以下的几点: 编译时实现多态(静态多态):通过CRTP技术…...
验证es启动成功
1. 查看命令行输出信息 在启动 Elasticsearch 时,命令行窗口会输出一系列日志信息。若启动成功,日志里通常会有类似下面的信息: plaintext [2025-05-06T13:20:00,000][INFO ][o.e.n.Node ] [node_name] started其中 [node_na…...
AI工场全面激活电商创意链
在当今科技飞速发展的时代,北京先智先行科技有限公司凭借其卓越的创新能力,推出了“先知大模型”、“先行AI商学院”以及“先知AIGC超级工场”这三款旗舰产品,在市场上掀起了不小的波澜。 传统电商设计流程,从需求确认到营销策…...
数 学 函数
gcd int gcd(int a,int b){while(a%b){int ca%b;ab;bc;}return b; } 错位排列 typedef long long ll; ll d(int n){if(n1) return 0;if(n2) return 1;return (n-1)*(d(n-1)d(n-2)); } 快速幂 //注意看是否有mod的需求 int q_pow(int a,int b){int ans1,tempa;while(b){if(…...
springboot集成langchain4j记忆对话
流式输出 LLM 一次生成一个标记(token),因此许多 LLM 提供商提供了一种方式,可以逐个标记地流式传输响应,而不是等待整个文本生成完毕。 这显著改善了用户体验,因为用户不需要等待未知的时间,几…...
C语言初阶:数组
目录 0.数组要讲的知识点 1.一维数组的创建和初始化 1.1 数组的创建: 1.2数组实例: 1.3 数组的初识化: 例子: 2.一维数组的使用 例子: 总结: 3.一维数组在内存中的存储 4.二维数组的创建和初始化 4.…...
案例分享 | 攻克ADAS开发测试难题,实现单元动态测试新突破
汽车行业中的代码动态测试:守护智能汽车的安全与质量 在当今汽车行业,智能网联汽车的快速发展让软件成为了汽车的核心竞争力之一。从自动驾驶辅助系统到车载信息娱乐系统,汽车中的软件数量和复杂度都在不断增加。然而,软件的复杂…...
K8S 基于本地存储的持久卷
假设有如下三个节点的 K8S 集群: k8s31master 是控制节点 k8s31node1、k8s31node2 是工作节点 容器运行时是 containerd 一、背景分析 阅读本文,默认您有 PV-PVC、hostPath 相关知识。 由于安全方面的考虑,K8S 官方并不推荐 hostPath …...
LED实验
目录 1.LED介绍 1.1LED原理图: 2.单片机运行代码的流程 3.进制的转换 4.C51数据类型 5.小编的单片机型号:STC89C52RC/LE52RC,最高波特率:9600 6.点亮一个LED 代码 步骤 代码: 7.LED闪烁 在STC内操作&#x…...
python+pytest接口自动化测试--日志记录
前言:代码可以直接复制使用 解决问题: 问题1:日志重复记录的问题,比如运行一个模块日志会记录很多遍(通过handlers是否存在解决的) 问题2:运行测试用例进行多个模块相互调用.日志记录不全的问题(通过共享公共的handlers解决问题) 首先写一个日志记录的工具 # 这个是个日志的…...
Android 蓝牙开发调试总结
Android 蓝牙开发调试总结 文章目录 Android 蓝牙开发调试总结一、前言二、蓝牙开发1、开关和连接控制2、相关日志3、相关广播4、demo示例 三、其他1、Android 蓝牙开发调试小结2、Android14 蓝牙启动流程3、Android14 蓝牙 BluetoothService 启动和相关代码介绍4、Android13 蓝…...
混淆矩阵(Confusion Matrix)
混淆矩阵(Confusion Matrix)是一个用于评估分类模型性能的工具,特别是在机器学习和统计学领域。它展示了模型预测结果与实际结果之间的关系。混淆矩阵通常用于二分类或多分类问题中,但也可以扩展到更多类别的情况。 一、混淆矩阵…...
C语言——操作符
一.操作符的分类 算术操作符: - * / %移位操作符:<< >>位操作符: & | ^赋值操作符: - * / % > & | ^单⽬操作符: ! -- & * - ~ sizeof …...
大数据处理利器:Hadoop 入门指南
一、Hadoop 是什么?—— 分布式计算的基石 在大数据时代,处理海量数据需要强大的技术支撑,Hadoop 应运而生。Apache Hadoop 是一个开源的分布式计算框架,致力于为大规模数据集提供可靠、可扩展的分布式处理能力。其核心设计理念是…...
追踪大型语言模型的思想(上)(来自针对Claude的分析)
概述 像 Claude 这样的语言模型并非由人类直接编程,而是通过大量数据进行训练。在训练过程中,它们会学习解决问题的策略。这些策略被编码在模型为每个单词执行的数十亿次计算中。对于我们这些模型开发者来说,这些策略是难以捉摸的。这意…...
系统 Python 与 Conda 环境的灵活切换
在现代 Python 开发中,经常需要在系统 Python 和 Conda 环境中的 Python 之间切换。无论是处理不同项目的依赖冲突,还是测试代码在不同 Python 版本下的兼容性,灵活切换 Python 环境都是开发者的必备技能。本文将详细介绍如何实现 Python 环境的灵活切换,并提供 Conda 命令…...
【HTTP】《HTTP 全原理解析:从请求到响应的奇妙之旅》
文章目录 一、HTTP 协议1.1、HTTP 是什么1.2、理解 "应用层协议"1.3、理解 HTTP 协议的工作过程1.4、HTTP协议格式1.5、协议格式总结 二、HTTP 请求1.1、认识 URL1.1.1、URL 基本格式1.1.2、关于 URL encode 1.2、认识 "方法"1.2.1 、GET 方法1.2.2、 POST…...
重生之我在2024学Fine-tuning
一、Fine-tuning(微调)概述 Fine-tuning(微调)是机器学习和深度学习中的一个重要概念,特别是在预训练模型的应用上。它指的是在模型已经通过大量数据训练得到一个通用的预训练模型后,再针对特定的任务或数据…...
若依前后端分离项目中可以删除哪些原若依有的?
在若依(RuoYi)前后端分离项目中完成二次开发后,可以删除以下未使用的模块和文件以简化项目结构。以下分模块和风险点说明: --- ### **一、后端(Spring Boot)可删除内容** #### 1. **未使用的功能模块** …...
element-plus中,vue3项目,el-input密码框禁止浏览器自动弹出浏览器历史密码提示框
原代码(密码框是text框): <el-form-item label"用户名" :label-width"formLabelWidth" v-if"!localOrhuawei" prop"userName"><el-input v-model"formDialog.userName" />&l…...
二叉树的遍历与构造
唉,好想回家,我想回家跟馒头酱玩,想老爸老妈。如果上天再给我一次选择的机会,我会选择当一只小动物,或者当棵大树也好,或者我希望自己不要有那么多多余的情绪,不要太被别人影响,开心…...
「Mac畅玩AIGC与多模态23」开发篇19 - Markdown 富文本输出工作流示例
一、概述 本篇基于格式化文本整合的经验,进一步介绍如何通过 LLM 输出标准 Markdown 内容,并在前端正确渲染出标题、列表、加粗等富文本格式,提升展示效果与内容结构可读性。 二、环境准备 macOS 系统Dify 平台已部署并可访问 三、在 Dif…...
记录学习《手动学习深度学习》这本书的笔记(十)
因为最近在做《语音与语言理解综合处理》的实验,所以打算先看第14章:自然语言处理:预训练和第15章:自然语言处理:应用,之后再来看第13章:计算机视觉。 第十四章:自然语言处理&#…...
Flowable7.x学习笔记(二十一)查看我的发起
前言 “查看我的发起”功能,就是将当前用户作为流程发起人启动的所有流程实例集中展示,帮助用户随时跟踪自己提交的业务请求的状态与历史,提升透明度与可控性。 业务人员通常不知道流程引擎底层如何运转,只关心“我提交的报销/申请…...
【Bootstrap V4系列】学习入门教程之 组件-折叠(Collapse)
Bootstrap V4系列 学习入门教程之 组件-折叠(Collapse) 折叠(Collapse)How it works一、Example二、Horizontal 水平的三、Multiple targets 多个目标四、Accordion example 手风琴示例 折叠(Collapse) 通…...
ROS1和ROS2使用桥接工具通信
前提:主从机在同一局域网内,可以互相ping通 我的两个设备其中一个无法连接wifi,ubuntu老生常谈的问题.....,获得新的技能:手机蓝牙提供网络,两个设备连接手机蓝牙就可以连接网络并且处于同一个局域网内。 我的主机为…...
尤雨溪宣布:Vue 生态正式引入 AI
在前端开发领域,Vue 框架一直以其易用性和灵活性受到广大开发者的喜爱。 而如今,Vue 生态在人工智能(AI)领域的应用上又迈出了重要的一步。 尤雨溪近日宣布,Vue、Vite 和 Rolldown 的文档网站均已添加了llms.txt文件,这一举措旨在让大型语言模型(LLM)更方便地理解这些…...
分布式id的两大门派!时钟回拨问题的解决方案!
2.1 两大门派 目前业界的分布式ID实现路径归结起来有两派:一派以雪花算法为代表,不强依赖DB能力,只使用分布式节点自身信息(时间戳节点ID序列号)的编码生成唯一序列,好处是去中心化、无单点风险࿱…...
QMK键盘固件配置详解
QMK键盘固件配置详解 前言 大家好!今天给大家带来QMK键盘固件配置的详细指南。如果你正在DIY机械键盘或者想要给自己的键盘刷固件,这篇文章绝对不容错过。QMK是目前最流行的开源键盘固件框架之一,它允许我们对键盘进行高度自定义。接下来&a…...
Jenkins 服务器上安装 Git
安装 Git # 更新包列表 sudo apt update# 安装 Git sudo apt install git 验证安装 # 检查 Git 版本 git --version 查看所有全局配置 git config --global --list 查看特定配置项 # 查看用户名配置 git config --global user.name# 查看邮箱配置 git config --global u…...
自由浮动时间和总浮动时间对比
一、自由浮动时间的定义 在项目进度管理中,自由浮动时间(Free Float)是指在不推迟项目后续任务最早开始时间的前提下,一个任务能够延迟的时间长度。它是针对单个任务而言的,主要考虑该任务与其紧后任务之间的关系。 …...
2025.05.07-华为机考第二题200分
📌 点击直达笔试专栏 👉《大厂笔试突围》 💻 春秋招笔试突围在线OJ 👉 笔试突围OJ 02. 社区智能安防系统设计 问题描述 随着智慧社区建设的发展,LYA小区需要设计一套高效的安防监控系统。该小区布局可以用一棵二叉树来表示,树的每个节点代表一户居民家庭。 为了…...
分布式架构详解
一、分布式架构的概念与设计目标 1. 基本概念 分布式架构(Distributed Architecture)是分布式计算技术的应用和工具,指将一个复杂系统拆分为多个独立的组件(或服务),并将这些组件部署在不同物理节点(服务…...
码蹄集——平方根X、整除幸运数
目录 MT1075 平方根X MT1078 整除幸运数 MT1075 平方根X 知识点: 上取整:ceil;下取整:floor;四舍五入:round 判断是否为完全平方数的方法:利用sqrt函数结果为double,将其结果相乘&a…...
【MATLAB源码-第277期】基于matlab的AF中继系统仿真,AF和直传误码率对比、不同中继位置误码率对比、信道容量、中继功率分配以及终端概率。
操作环境: MATLAB 2022a 1、算法描述 在AF(放大转发)中继通信系统中,信号的传输质量和效率受到多个因素的影响,理解这些因素对于系统的优化至关重要。AF中继通信的基本架构由发射端、中继节点和接收端组成。发射端负…...
ACE-Step - 20秒生成4分钟完整歌曲,音乐界的Stable Diffusion,支持50系显卡 本地一键整合包下载
ACE-Step 是由ACE Studio与StepFun联合开发的音乐生成模型,被誉为“音乐界的Stable Diffusion”。该模型以其惊人的生成速度和多样化功能引发行业热议,支持19种语言,可在短短20秒内生成一首长达4分钟的完整音乐作品,效率比主流模型…...
007 Linux 开发工具(上)—— vim、解放sudo、gc+
🦄 个人主页: 小米里的大麦-CSDN博客 🎏 所属专栏: Linux_小米里的大麦的博客-CSDN博客 🎁 GitHub主页: 小米里的大麦的 GitHub ⚙️ 操作环境: Visual Studio 2022 文章目录 Linux 开发工具(上)Linux 编辑器 —— vim…...