Android开发之触摸事件处理机制详解

Android的事件分发 一、Touch事件和绘制事件的异同之处Touch事件和绘制事件很类似,都是由ViewRoot派发下来的,但是不同之处在绘制事件是由应用中的某个View发起请求,一层一层上传到ViewRoot,再有ViewRoot下发绘制,传递canvas给所有子View让其绘制自身,绘制好后,再通知WMS进行画到屏幕上。而Touch事件是由硬件捕获到触摸后由系统传递给应用的ViewRoot,再由ViewRoot往下 阅读详情

android触碰消息传递机制



用户的每次触碰(onClick,onLongClick,onScroll,etc.)都是由一个ACTION_DOWN+n个ACTION_MOVE+1个ACTION_UP组成的,用户触碰必先有个ACTION_DOWN响应,用户触碰结束必然会有个ACTION_UP。(当然如果在途中被拦截,就可能不会有了!)那么View是如何分发消息和拦截消息呢?


1.View及其子类都会有的两个方法:


public boolean dispatchTouchEvent(MotionEvent ev) 这个方法用来分发TouchEvent
public boolean onTouchEvent(MotionEvent ev) 这个方法用来处理TouchEvent
2.特殊的View子类ViewGroup则还有一个方法:


public boolean onInterceptTouchEvent(MotionEvent ev) 这个方法用来拦截TouchEvent
3.分发


dispatchTouchEvent 收到触碰,则向最外层的View传递消息,再向子层的View分发
4.拦截:


onInterceptTouchEvent 拦截返回true表示要拦截消息,不要再向子View传递(这里的子View不是继承关系,而是包容关系)。返回false则表示不拦截消息,可以继续向下一层级的View传递消息,子View将可以dispatchTouchEvent 收到触碰消息再分发消息


5.消息处理:


onTouchEvent 处理事件,拦截了消息,或者是最后一个收到消息的View调用此方法来处理事件,若返回true,则表示正确接收并处理。若返回false则表示没有被处理,将向父View传递(这里的父View不是继承关系,而是包容关系)


Android事件模型之interceptTouchEvnet ,onTouchEvent关系正解

参考文档:

http://blog.youkuaiyun.com/liutao5757124/article/details/6097125


首先,看Android的官方文档正解


onInterceptTouchEvent()与onTouchEvent()的机制:

  1. down事件首先会传递到onInterceptTouchEvent()方法


  2. 如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之后return false,

  那么后续的move, up等事件将继续会先传递给该ViewGroup,之后才和down事件一样传递给最

  终的目标view的onTouchEvent()处理


  3. 如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之后return true,

  那么后续的move, up等事件将不再传递给onInterceptTouchEvent(),而是和down事件一样

  传递给该ViewGroup的onTouchEvent()处理,注意,目标view将接收不到任何事件。


  4. 如果最终需要处理事件的view的onTouchEvent()返回了false,那么该事件将被传递至其上一

  层次的view的onTouchEvent()处理


  5. 如果最终需要处理事件的view 的onTouchEvent()返回了true,那么后续事件将可以继续传递

  给该view的onTouchEvent()处理

这是官方文档的说法,要是自己没亲自去写个程序观察哈,基本上没法理解,所以上程序先,然后分析:



布局文件main.xml

Java代码   收藏代码
  1. <span style="font-size: small;"><?xml version="1.0" encoding="utf-8"?>  
  2. <com.hao.LayoutView1 xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical" android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent">  
  5.     <com.hao.LayoutView2  
  6.         android:orientation="vertical" android:layout_width="fill_parent"  
  7.         android:layout_height="fill_parent" android:gravity="center">  
  8.         <com.hao.MyTextView  
  9.             android:layout_width="wrap_content" android:layout_height="wrap_content"  
  10.             android:id="@+id/tv" android:text="AB" android:textSize="40sp"  
  11.             android:textStyle="bold" android:background="#FFFFFF"  
  12.             android:textColor="#0000FF" />  
  13.     </com.hao.LayoutView2>  
  14. </com.hao.LayoutView1>   
  15. </span>  

 第一层自定义布局LayoutView1.java

Java代码   收藏代码
  1. <span style="font-size: small;">package com.hao;  
  2.   
  3. import android.content.Context;  
  4. import android.util.AttributeSet;  
  5. import android.util.Log;  
  6. import android.view.MotionEvent;  
  7. import android.widget.LinearLayout;  
  8.   
  9. public class LayoutView1 extends LinearLayout {  
  10.      private final String TAG = "LayoutView1";   
  11.      public LayoutView1(Context context, AttributeSet attrs) {   
  12.          super(context, attrs);   
  13.          Log.e(TAG,TAG);   
  14.      }  
  15.        
  16.      @Override   
  17.      public boolean onInterceptTouchEvent(MotionEvent ev) {   
  18.          int action = ev.getAction();   
  19.          switch(action){   
  20.          case MotionEvent.ACTION_DOWN:   
  21.               Log.e(TAG,"onInterceptTouchEvent action:ACTION_DOWN");   
  22. //              return true; 在这就拦截了,后面的就不会得到事件  
  23.               break;  
  24.         case MotionEvent.ACTION_MOVE:   
  25.               Log.e(TAG,"onInterceptTouchEvent action:ACTION_MOVE");   
  26.               break;   
  27.          case MotionEvent.ACTION_UP:   
  28.               Log.e(TAG,"onInterceptTouchEvent action:ACTION_UP");   
  29.               break;   
  30.          case MotionEvent.ACTION_CANCEL:   
  31.               Log.e(TAG,"onInterceptTouchEvent action:ACTION_CANCEL");   
  32.               break;   
  33.          }   
  34.          return false;   
  35.      }   
  36.   
  37.      @Override   
  38.      public boolean onTouchEvent(MotionEvent ev) {   
  39.          int action = ev.getAction();   
  40.          switch(action){   
  41.          case MotionEvent.ACTION_DOWN:   
  42.               Log.e(TAG,"onTouchEvent action:ACTION_DOWN");   
  43.               break;   
  44.          case MotionEvent.ACTION_MOVE:   
  45.               Log.e(TAG,"onTouchEvent action:ACTION_MOVE");   
  46.               break;   
  47.          case MotionEvent.ACTION_UP:   
  48.               Log.e(TAG,"onTouchEvent action:ACTION_UP");   
  49.               break;   
  50.          case MotionEvent.ACTION_CANCEL:   
  51.               Log.e(TAG,"onTouchEvent action:ACTION_CANCEL");   
  52.               break;   
  53.          }   
  54.          return true;   
  55. //         return false;  
  56.      }   
  57.        
  58.      @Override   
  59.      protected void onLayout(boolean changed, int l, int t, int r, int b) {   
  60.          // TODO Auto-generated method stub   
  61.          super.onLayout(changed, l, t, r, b);   
  62.      }   
  63.   
  64.      @Override   
  65.      protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {   
  66.          // TODO Auto-generated method stub   
  67.          super.onMeasure(widthMeasureSpec, heightMeasureSpec);   
  68.      }   
  69. }</span>  

 第二层布局LayoutView2.java

Java代码   收藏代码
  1. <span style="font-size: small;">package com.hao;  
  2.   
  3. import android.content.Context;  
  4. import android.util.AttributeSet;  
  5. import android.util.Log;  
  6. import android.view.MotionEvent;  
  7. import android.widget.LinearLayout;  
  8.   
  9. public class LayoutView2 extends LinearLayout {  
  10.       
  11.     private final String TAG = "LayoutView2";   
  12.     public LayoutView2(Context context, AttributeSet attrs) {   
  13.        super(context, attrs);   
  14.        Log.e(TAG,TAG);   
  15.     }   
  16.       
  17.     @Override   
  18.     public boolean onInterceptTouchEvent(MotionEvent ev) {   
  19.        int action = ev.getAction();   
  20.        switch(action){   
  21.        case MotionEvent.ACTION_DOWN:   
  22.            Log.e(TAG,"onInterceptTouchEvent action:ACTION_DOWN");  
  23. //           return true;  
  24.            break;   
  25.        case MotionEvent.ACTION_MOVE:   
  26.            Log.e(TAG,"onInterceptTouchEvent action:ACTION_MOVE");   
  27.            break;   
  28.        case MotionEvent.ACTION_UP:   
  29.            Log.e(TAG,"onInterceptTouchEvent action:ACTION_UP");   
  30.            break;   
  31.        case MotionEvent.ACTION_CANCEL:   
  32.            Log.e(TAG,"onInterceptTouchEvent action:ACTION_CANCEL");   
  33.            break;   
  34.        }   
  35.        return false;   
  36.     }   
  37.   
  38.     @Override   
  39.     public boolean onTouchEvent(MotionEvent ev) {   
  40.        int action = ev.getAction();   
  41.        switch(action){   
  42.        case MotionEvent.ACTION_DOWN:   
  43.            Log.e(TAG,"onTouchEvent action:ACTION_DOWN");   
  44.            break;   
  45.        case MotionEvent.ACTION_MOVE:   
  46.            Log.e(TAG,"onTouchEvent action:ACTION_MOVE");   
  47.            break;   
  48.        case MotionEvent.ACTION_UP:   
  49.            Log.e(TAG,"onTouchEvent action:ACTION_UP");   
  50.            break;   
  51.        case MotionEvent.ACTION_CANCEL:   
  52.            Log.e(TAG,"onTouchEvent action:ACTION_CANCEL");   
  53.            break;   
  54.        }   
  55. //       return true;   
  56.        return false;  
  57.     }   
  58. }  
  59. </span>  

 自定义MyTextView.java

Java代码   收藏代码
  1. <span style="font-size: small;">package com.hao;  
  2.   
  3. import android.content.Context;  
  4. import android.util.AttributeSet;  
  5. import android.util.Log;  
  6. import android.view.MotionEvent;  
  7. import android.view.View;  
  8. import android.widget.TextView;  
  9.   
  10. public class MyTextView extends TextView {  
  11.     private final String TAG = "MyTextView";   
  12.     public MyTextView(Context context, AttributeSet attrs) {   
  13.        super(context, attrs);   
  14.        Log.e(TAG,TAG);   
  15.     }   
  16.   
  17.     @Override   
  18.     public boolean onTouchEvent(MotionEvent ev) {   
  19.        int action = ev.getAction();   
  20.        switch(action){   
  21.        case MotionEvent.ACTION_DOWN:   
  22.            Log.e(TAG,"onTouchEvent action:ACTION_DOWN");   
  23.            break;   
  24.        case MotionEvent.ACTION_MOVE:   
  25.            Log.e(TAG,"onTouchEvent action:ACTION_MOVE");   
  26.            break;   
  27.        case MotionEvent.ACTION_UP:   
  28.            Log.e(TAG,"onTouchEvent action:ACTION_UP");   
  29.            break;   
  30.        case MotionEvent.ACTION_CANCEL:   
  31.            Log.e(TAG,"onTouchEvent action:ACTION_CANCEL");   
  32.            break;   
  33.        }   
  34.        return false;   
  35. //       return true;  
  36.     }   
  37.   
  38.     public void onClick(View v) {   
  39.        Log.e(TAG, "onClick");   
  40.     }   
  41.   
  42.     public boolean onLongClick(View v) {   
  43.        Log.e(TAG, "onLongClick");   
  44.        return false;   
  45.     }   
  46. }  
  47. </span>  

 其实代码很简单,就是自定义了View,在View里面都重写了interceptTouchEvnet (),和onTouchEvent(),然后测试其返回值,对监听的影响,关键是自己动手,逐个测试,并预测结果,等你能预测结果的时候,也就懂了,需要修改的地方就是interceptTouchEvnet 和onTouchEvent的返回值,他们决定了事件监听的流程,下面我画了一张图,如有不足之处欢迎指正,谢谢!


下面是我的正解:

基本的规则是: 
      *1.down事件首先会传递到onInterceptTouchEvent()方法 
      * 
      * 2.如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之后return false(不拦截),
      * 那么后续的move, up等事件将继续会先传递给该ViewGroup,之后才和down事件一样传递给最终的目标view的onTouchEvent()处理。 
      *
      * 3.如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之后return true(拦截,那么后面的move,up事件不需要在看因为已经拦截了, 我们直接拿去处理onTouchEvent()就可以了),那么后续的move, up等事件将不再传递给onInterceptTouchEvent(), 而是和down事件一样传递给该ViewGroup的onTouchEvent()处理,注意,目标view将接收不到任何事件。 下面例子演示:
      * 1:LayoutView1(31375): onInterceptTouchEvent action:ACTION_DOWN
      * 2:LayoutView2(31375): onInterceptTouchEvent action:ACTION_DOWN
      * 3:LayoutView2(31375): onTouchEvent action:ACTION_DOWN
      * 4:LayoutView1(31375): onInterceptTouchEvent action:ACTION_MOVE
      * 5:LayoutView2(31375): onTouchEvent action:ACTION_MOVE
      * 6:LayoutView1(31375): onInterceptTouchEvent action:ACTION_MOVE
      * 7:LayoutView2(31375): onTouchEvent action:ACTION_MOVE
      * 8:LayoutView1(31375): onInterceptTouchEvent action:ACTION_UP
      * 9:LayoutView2(31375): onTouchEvent action:ACTION_UP
      * 该设置为:
      * onInterceptTouchEvent:LayoutView1为false,LayoutView2为true
      * onTouchEvent:LayoutView2为true
      * 故而事件在LayoutView2(onInterceptTouchEvent:返回true)时被拦截并处理,根据上面说法就是LayoutView2后续的MOVE,UP操作都不在经过onInterceptTouchEvent,直接
      * 交给onTouchEvent处理,结果也的确如此。(见:LayoutView2的3,5,7,9,第一次是onInterceptTouchEvent处理如1,以后交给onTouchEvent)
      * 而LayoutView1都还是要经过onInterceptTouchEvent(见LayoutView1的4,6,8)
      * 
      * 4.如果最终需要处理事件的view的onTouchEvent()返回了false(没能处理这个事件,不能丢在传回来让父继续),
      * 那么该事件将被传递至其上一层次的view的onTouchEvent()处理。 
      * **************************************************************************
      * 感觉像是一个圈,然后一直在找一个能处理这个消息的人,如果找到了就结束,没找到就循环,直到回到发出消息的那个人
      * 注(对下面):没有标注的DOWN表示拦截事件onInterceptTouchEvent,标注了onTouchEvent就是处理事件
      * a.如果都没处理(onInterceptTouchEvent返回false):
A(DOWN)-->B(DOWN)-->C(onTouchEvent DOWN)-->B(onTouchEvent DOWN)-->A(onTouchEvent DOWN),没有执行UP事件,注意有MOVE的话,在DOWN和UP之间,下面的都一样。
      *b. B处理(B的onInterceptTouchEvent返回true):
A(DOWN)-->B(DOWN)-->B(onTouchEvent)-->A(onTouchEvent UP)-->B(onTouchEvent UP)-->(over)
      *
形象说明:如果父亲不拦截消息就传给儿子,如果儿子要这个消息就处理(DOWN),结束,然后有父亲1--父亲2--儿子以此释放消息(UP)。 然是如果儿子对这个消息置之不理,那这个消息又传回父亲,由父亲来处理即。

下面给出了5中情况(不拦截表示onInterceptTouchEvent返回false):
      * 11** 父亲1(LayoutView1不拦截false)---父亲2(LayoutView2不拦截false)--儿子(MyTextView,onTouchEvent return true)--结束
      * 22** 父亲1(LayoutView1不拦截false)---父亲2(LayoutView2不拦截false)--儿子(MyTextView,onTouchEvent return false)--回传给父亲2(onTouchEvent return true)--结束
      * 33** 父亲1(LayoutView1不拦截false)---父亲2(LayoutView2不拦截false)--儿子(MyTextView,onTouchEvent return false)--回传给父亲2(onTouchEvent return false)--父亲1(onTouchEvent return true)--结束(如果都没处理不在执行UP ACTION)
      * 44** 父亲1(LayoutView1拦截true)--父亲1(onTouchEvent return true)--结束          (DOWN--DOWN(onTouchEvent)--UP(onTouchEvent))
      * 55** 父亲1(LayoutView1拦截false)--父亲2(LayoutView2拦截true)--父亲2(onTouchEvent return false)--父亲1(onTouchEvent return true)--结束      (DOWN1--DOWN2--DOWN(2 onTouchEvent)--DOWN(1 onTouchEvent)--UP(1 onTouchEvent))(1:父亲2,2:父亲2)
      * 
      * ***************************************************************************
      * 5.如果最终需要处理事件的view 的onTouchEvent()返回了true,那么后续事件将可以继续传递给该view的onTouchEvent()处理。 
      */

下面给出一张处理的流程图:


 下附源代码:

Android触摸事件机制 最近做了一个类似桌面应用图标可以点击,长按拖动效果,然后研究了下android触摸事件机制。 Android中的事件分为按键事件和触摸事件,这里对触摸事件进行阐述。Touch事件是由一个ACTION_DOWN,n个ACTION_MOVE,一个ACTION_UP组成onClick,onLongClick,onScroll等事件。Android中的控件都是继承View这个基类的,而控件分为两种:一种 阅读详情

相关推荐

Android Studio学习:安卓触摸事件

安卓触摸事件

m0_62491877的博客 2026

Android事件模型之interceptTouchEvnet ,onTouchEvent关系正解

参考文档: http://blog.youkuaiyun.com/liutao5757124/article/details/6097125 首先,看Android的官方文档正解 onInterceptTouchEvent()与onTouchEvent()的机制:   1. down事件首先会传递到onInterceptTouchEvent()方法   2. 如果该ViewGroup的o...

haodynasty的专栏 264

【Android面试八股文】如果 onTouchEvent()方法返回false,onClick()方法还会执行么?

在 Android 中,拦截事件通常指阻止事件继续传递或者消费事件,以防止它继续触发其他后续事件(比如onClick()在方法中,如果返回false,表示当前 View 没有处理该事件,Android 系统会继续将事件传递给后续的 View 或者执行点击事件的回调。

字节卷动 649

Android高级UI面试题汇总(含详细解析 十三)

责任链模式是行为型设计模式中的一个。责任链模式的定义:为了避免请求发送者与多个请求处理者耦合在一起,于是将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。

Misdirection_XG的博客 188

Android事件分发机制:深入理解与实践

它负责将用户的触摸事件、按键事件和其他输入事件传递给正确的视图组件进行处理。在事件分发的过程中,dispatchTouchEvent()方法被调用,它负责将触摸事件分发给子视图。然后,我们记录了事件的分发结果,并返回该结果。事件分发机制的基本原理是,当用户触摸屏幕时,事件首先由顶级视图(通常是Activity的根视图)接收。它负责将用户的触摸事件、按键事件和其他输入事件传递给正确的视图组件进行处理。通过上述调用顺序,我们可以看到事件是如何从顶级视图传递到子视图,并且每个方法在事件分发过程中的角色和作用。

TechCraze的博客 224

Android触摸事件处理机制的深入测试与应用

Android的触摸事件处理涉及几个关键方法:, 和。这些方法协同工作,决定了事件如何在视图层级中传递和处理。理解这些方法的运作机制能够帮助开发者更有效地控制触摸事件的流向,进而优化性能和用户交互。自定义ViewGroup的事件拦截行为通常涉及重写方法。例如,如果你想自定义一个滑动效果,可以通过判断滑动方向来决定是否拦截事件,示例代码如下:@Override// 不拦截此类事件// 处理自定义滑动逻辑// 重置状态,例如记录当前点的位置break;

weixin_42588877的博客 971

Android触摸反馈(回顾整理):触摸事件的分发机制、拦截机制。

Android触摸反馈:触摸事件的分发机制、拦截机制。

手写我对你的温柔 3568

AI智能体升级实战:从规则匹配到Function Call,准确率提升86%的技术选型之路

AI智能体升级实战:从规则匹配到Function Call的技术演进 文章记录了AI邮件助手从传统规则匹配升级到Function Call的技术迭代过程。通过案例分析,揭示了规则匹配的三大核心问题:覆盖不全(用户表达千变万化)、组合困难(多条件容易漏掉)、维护噩梦(每个需求都要新增规则)。测试数据显示,规则匹配在复杂查询中的准确率仅51%,严重影响用户体验。 技术团队对比了三种升级方案:1) 继续优化规则匹配(天花板明显);2) 微调专用NLP模型(成本高);3) 采用Function Call(灵活高效)

yweng18的博客 1079

onTouch返回true和false的区别,如何解决onTouch和onClick冲突

在开发中,我们会遇到某个图标可拖动的需求,我们会同时使用到onClick和onTouch事件,这个时候onClick和onTouch会发生冲突。 1、我们先比较他们onClick和onTouch 的用法,从下面代码可以发现,onTouch有返回,而onClick无返回。这个时候你会好奇,返回true和false有什么区别?下面来分析有什么不同和区别。

jianesrq0724的博客 3万+

【自动驾驶规划】Lattice Planner

Lattice Planner简介 LatticePlanner算法属于一种局部轨迹规划器,输出轨迹将直接输入到控制器,由控制器完成对局部轨迹的跟踪控制。因此,Lattice Planner输出的轨迹是一条光滑无碰撞满足车辆运动学约束和速度约束的平稳安全的局部轨迹。Lattice Planner的输入端主要由三部分组成,感知及障碍物信息、参考线信息及定位信息。局部规划模块的输出是带有速度信息的一系列轨迹点组成的轨迹,其保证了车辆控制器在车辆跟踪控制过程中的平稳性和安全性。 局部规划模块的输出是带有速

uytguytgf的博客 6497

9.Vue前端使用iframe集成帆软报表的单点登录

CPT普通报表的地址:【帆软的服务http】+【/webroot/decision/view/report?【帆软的服务http】+【/webroot/decision/view/form?// fineReportHttp:帆软部署的地址。//如果为ie浏览器则页面加载完成后立即执行。// fineLinkSrc:帆软报表的url。//其他浏览器则重新加载onload事件。// 拿到配置的帆软报表的地址参数。//判断是否为ie浏览器。// 帆软报表登录和打开。// 帆软报表登录和打开。

qq_27860623的博客 4649

Activity的事件分发机制

MotionEvent的4种类型 事件类型 具体动作 MotionEvent.ACTION_DOWN 按下(所有事件的开始) MotionEvent.ACTION_UP 抬起 MotionEvent.ACTION_MOVE 滑动 MotionEvent.ACTION_CANCEL 结束事件(非人为原因) 事件分发的本质是将点击事件(MotionEvent)传递到某个...

u013728021的博客 750

Ubuntu Server 22.04.5系统安装教程

该教程主要是演示在服务器上安装Ubuntu server 22.04系统的详细步骤,主要包含,安装系统前的准备(镜像的下载,启动盘的制作),安装系统时的语言选择,网络设置,切换镜像源(可根据实际需求来配置,本文使用清华镜像源),手动分区,用户设置,ssh服务安装等。以上就是关于Ubuntu Server 22.04系统安装的详细过程。

逆水行舟,不进则退。 7762

Material Design事件处理:RippleManager与点击事件管理终极指南

Material Design作为现代移动应用设计的黄金标准,其核心交互体验之一就是优雅的涟漪效果。📱 这个开源Material Design库通过RippleManager组件,为Android开发者提供了完整的点击事件管理解决方案,让应用具备原生的Material Design交互体验。 ## 什么是RippleManager?✨ RippleManager是Material Desig

gitblog_00551的博客 323

FPGA实战:手把手教你用Verilog驱动4.3寸RGB触摸屏(附完整代码)

本文详细介绍了如何使用Verilog语言在FPGA上驱动4.3寸RGB触摸屏,包括时序设计、信号交互原理及完整代码实现。通过双计数器引擎设计和参数化模块,开发者可以高效构建800*480分辨率的显示驱动,并解决工程实践中的信号完整性和时序收敛问题。

rice5的博客 703

保姆级教程:手把手教你给联想System x 3650 M5服务器配置RAID 5并U盘装系统

本文提供联想System x 3650 M5服务器配置RAID 5并U盘安装系统的详细教程,特别适合零基础运维人员。从准备工作、RAID 5配置到U盘引导和系统安装,涵盖全流程关键步骤与常见问题解决方案,帮助用户高效完成服务器部署。

weixin_42535703的博客 358

Android悬浮窗开发实战:从权限申请到拖拽点击事件处理(附完整Kotlin源码)

本文详细解析了Android悬浮窗开发的完整流程,从关键的SYSTEM_ALERT_WINDOW权限动态申请,到使用WindowManager创建和管理悬浮窗口,并重点阐述了如何通过触摸事件监听精准区分拖拽与点击意图。文章提供了可直接集成的Kotlin源码,涵盖了前台服务载体、事件处理逻辑及兼容性优化等实战要点。

c2d3e4f的博客 760

【物联网】探索NE555:一款经典的集成电路(超详细)

NE555是一种集成电路,其内部结构包括比较器、RS触发器、电压比较器和输出级三个主要功能模块,外部引脚则提供了与其他电路元件进行连接的接口。NE555的设计目的是为了提供一种简单方便的定时器解决方案,它广泛应用于模拟和数字电路中。NE555作为一款经典的集成电路,具备设计简单、易于使用和稳定可靠的特点,在电子领域发展了广泛的应用。从单稳态模式到多稳态模式,再到振荡器模式,NE555可以满足不同的需求,并且可以与其他电路元件灵活组合,扩展其功能。然而,需要注意的是NE555也有一些限制。

Goforyouqp的博客 6万+

Android弹窗事件处理终极指南:BasePopup点击、滑动、键盘交互全掌握

BasePopup是Android平台上一款通用便捷的PopupWindow弹窗库,它提供了丰富的事件处理机制,帮助开发者轻松实现弹窗的点击、滑动和键盘交互功能。本文将详细介绍BasePopup的事件处理方法,让你快速掌握弹窗交互的核心技巧。 ## 点击事件处理:轻松实现按钮交互 点击事件是弹窗最基本也是最常用的交互方式。在BasePopup中,你可以通过设置监听器来处理弹窗内视图的点击事件。

gitblog_00041的博客 332

基于STM32的太阳能充电宝设计_资料编号31

系统硬件包括主控 STM32F103C8T6、0.96 OLED 显示屏、蜂鸣器、电源自锁开关、温度传感器 DS18B20、继电器、5 V DC 升压模块 、TB4056、18650锂电池、9 V太阳能板、稳压降压 5 V三极管。电源供应:锂电池为系统供电,9 伏太阳能板经 5 伏降压稳压三极管降压为 5 伏后传送到 TP4056,TP4056 为锂电池供电,因锂电池电压 3.7 伏,通过 5 伏 DC 升压模块升压到 5 伏为整个系统提供 5 伏电压。

嵌入式阿齐Archie 1万+

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Android 输入系统

发现大神系列文章链接,希望对你有帮助。 https://blog.youkuaiyun.com/cjc_karen/article/details/51386793 //站在大神肩膀上,深入理解 Android事件分发机制 https://blog.youkuaiyun.com/chunqiuwei/article/details/41084921 //android事件拦截处理机制详解 https://blog....

平凡之路 564

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

android学习总结

经过了一段时间的android学习,特总结Android开发原创教程,希望能够对同为新手的我们有些许的帮助。 1.一位大神的学习总结,很不错,很全,啥都有 http://www.apkbus.com/android-18056-1-1.html 2.教你用animation做android电视关闭的动画效果 http://www.apkbus.com/android...

weixin_34248258的博客 130

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

ViewGroup 事件分发机制

上一章说了view的触摸事件的传递机制,这一章就讲讲ViewGrou的事件传递机制,ViewGroup 是 View 的子类,也就是说View包含的功能,ViewGroup 都有,并且做了相应的修改和扩展。 ViewGroup 比着 View 多了一个方法 onInterceptTouchEvent(MotionEvent event)。我们平时的焦点触摸事件,都是通过ViewGroup容器传...

Deaht_Huimie的博客 377

安卓触摸事件分发机制分析

🎯 一句话总结:触摸事件(TouchEvent)会从Activity层开始,按从外到内的方式传递给每一个 ViewGroup/View,直到某个 View消费(consume)它,事件传递就会停止。📌 事件分发三个关键方法方法名所在类作用说明所有 View/ViewGroup事件分发入口,决定是否继续向下传递仅 ViewGroup是否拦截事件,阻止传递给子 View所有 View/ViewGroup事件的最终处理者(消费者)DecorView是一个应用窗口的根容器,它本质上是一个。

WriteBug001的博客 971
上一篇: Android开发之调节屏幕亮度
下一篇: Android开发之各种双向侧滑菜单的实现
minimicall
博客等级 码龄18年 407粉丝 174原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值