大众号:字节数组,热衷于共享 Android 体系源码解析,Jetpack 源码解析、抢手开源库源码解析等面试必备的知识点,欢迎关注
View 的作业分发机制一向是 Android 开android下载发中比较难啃的一块知识点,想要理顺 MotionEvent 在 ViewGroup 和 View 这两者之间流通的规则非常不容易,整个进程触及分发、阻遏、消费三个进程,每个进程依据回来值的不同在流程就源码年代会有很大不同,且 Act优先级和劣后级的差异ivity 也会参与进这个进程,不参照源码进行剖析的话就很难android是什么手机牌子理解接触作业的分发规则。在良久android/yunos前我就想过要来动笔写这一块知识点,春节期间就熬夜肝了一篇,期望对你有所帮忙
一、坐标系
Android 中的坐标系能够分为两种:屏幕坐标系 和 View 坐标系
1、屏幕坐标系
屏幕坐标系以屏幕左上角作为坐标原点,水平向右方向为 X 轴正轴方向,竖直向下方向为 Y 轴正轴方向
2、View 坐标系
View 坐标系以 View 地址的 ViewGroup 的左上角作为坐标原点,水平向右方向为 X 轴正轴方向,竖直向下方向为 Y 轴giticomfort正轴方向。View 类包括了以下几个办法用于获取其相对父容器 ViewGroup 的间隔:
- getLeft()。View 左面到 ViewGroup 左面之间的间隔
- getTop()。View 顶部到 ViewGroup 顶部之间的间隔
- getRight()。View 右侧到 ViewGroup 左面之间的间隔
- gandroid手机etBottom()。View 底部到 ViewGroup 顶部之间的间隔
Viandroid11ew 就依赖于这四个间隔值来计算宽高巨细
public final int getWidth()源码编辑器 {
return mRight - mLeft;
}
public final int getHeight() {
return mgiti轮胎是什么品牌Bottom - mT源码买卖网站源码op;
}
二、MotionEvent
接触作业最常见的有以下三种类型:
- ACTION_DOWN:用户手指的按下操作,是用户每次接触屏幕时触发的第一个作业
- ACTION_MOVE:用户手指按压屏背地里,在松开手指优先级和劣后级的差异之前假定滑动屏幕超出必定的阈值,则发生了 ACTION_MOVE 作业
- ACTION_UP:用户手指脱离屏幕时触发的操作,是当次接触操作的究竟一个作业
一次无缺的作业序列包括用户从按下屏幕到脱离屏幕之间触发的悉数作业,在这个序列傍边,ACTION_DOWN 和 ACTION_UP 是必定会有的,有且只需一个,ACTIO面试技巧N_MOVE 则视状况而定,数量大于等于零(这儿不考虑多点触控的状况)
每个作业都会被包装为 MotionEvent 类
fun dispatchTouchEvent(event: MotionEvent) {
when (event.action) {
MotionEvent.优先级英文ACTION_DOWN -&android下载软件appgt; TODO()
MotionEveandroid是什么手机牌子nt.ACTION_MOVE -> TODO(优先级英文)
MotiongiteeE面试必问10大问题答复vent.ACTION_UP -> TODO()
}
}
MotionEvent 包括了该次接触作业发生的坐标点,分为两组不同的办法
//依据 View 左上角获取到giti的间隔
motio源码编辑器nEvent.gandroid什么意思etX();
motionEveandroid下载nt.getY();
//依据屏幕左上角获源码本钱取到的间隔
motigithub中文官网onEvent.g面试毛遂自荐3分钟通用etRawX();
motionEvent.getRawY();
此外,体系内置了一个最小滑动间隔值,只需先后两个坐标点之间的间隔超出该值,才会以为归于滑动作业
ViewCandroid界面设计onfiguration.ggithub是干什么的et(Co优先级英文ntext).getScaledTouchSlop源码网()
三、作业分发的三个阶段
在整个作业分发进程中,咱们首要接触的是 ViewGrou面试必问10大问题答复p 和 View 这两种视图类型。一次无缺的作业分发进程会包括三个阶段,即作业的发布giticomfort、阻遏和消费,这三个进程别离对应声明在 View 和 ViewGrou源码网p 中的三个办法
1、发布
作业优先级排序的发布对应着如下办法
public boolean dispatchTouchEvent(MotionEvent ev)
Android 中的视图(View、ViewGroup、Activity 等)接纳到的优先级接触工android体系作都是优先级和劣后级的差异经过这个办法来优先级进行分发的,假定作业能够传递给当时视图,则此办法必定会被调用,优先级是什么意思即视图接纳到的接触作业都需求经过该办法来进行分发。该办法的回来值用于标明该视图或许内嵌视图是否消费了该作业。假定当时视图类型是 ViewGroup,该办法内部会调用 onInterceptTouchEvent(Motio源码nEvent)
办法来判别是否阻遏该作业源码买卖网站源码
2、阻遏
作业的阻遏对应着如下办法
puandroid11blic boolean onInterceptTouchEvent(MotionEveAndroidnt eandroid手机v)
ViewGr源码共享网oup 包括该源码共享网办法,View 中不存在。该办法经过回来值来标明是否需求阻遏对应的作业。回来 true 则标明阻遏这个源码买卖网站源码作业,不持续发布给子视图,并将作业交由自身的 onTouchEvent(MotionEvent evengitlabt)
办法来进行处理;回来 false 则标明不阻遏作业,持续传递给子视图。假定 ViewGroup 阻优先级挠了某个作业,那么在同一个作业序列傍边,此办法不会被再次调用
3、消费
作业的面试必问10大问题答复消费github中文官网对应着如下办法
public boole优先级调度算法an onTouchEvent(MotionEvent event)
该办法回来 true 标明当时视图现已处理了对应的作业,作业将在这儿完毕消费,间断传递;回来 false 标明当时视图不处理这个作业,作业会被传递给android手机其它视图
4、三者的联络
ViewGroup 无缺包括以上三个进程,而 View 只包括分发和消费两个,既 View 类优先级 劣后级不包括 o优先级最高的运算符nIntercept优先级和劣后级的差异TouchEvent(MotionEvent)
办法。三个办法之间的联络能够面试问题用如下伪代码来标明:
fun dispatchTouchEvent(event: MotionEvent): Bogiticomfortolean {
var consume = false
consume = if (onInterceptTouchEvent(eve优先级nt)) {
onTouchEvent(even面试技巧和注意事项t)
} else {
child面试毛遂自荐3分钟通用.diandroid体系spatch面试技巧和注意事项TouchEvent(e源码编辑器编程猫下载ve面试技巧nt)
}
return consume
}
当接触作业发生时,作业优先级 劣后级分发流程会依照如下实施:
- 根 ViewGroup 最早接纳到 MotionEvent,其 dispatchTouchEvent 办法会被调用到,该办法内部会调用 onInterceptTouchEvent 办法来判别是否要阻面试挠作业
- ViewGroup 的 onIntegitirceptTouchEve面试nt 办法假定回来 true,则标明当时 ViewGAndroidroup 要阻遏作业,不然就会去调面试毛遂自荐范文通用用android下载 child(内嵌的 ViewGroup 或许是git指令 Vie优先级调度算法w)重复分发进程
- View 和 ViewGroup 的 onTouchEvent 办法用来判别是否要消费该作业,源码怎样做成app软件假定回来了 true 则标明作业已被消费,间断源码传递
当然,View 的作业分发进程不是上述介绍的那么简略,实践上作业的流通进程很杂乱,依据每个Git办法回来值的不同,作业序列的流通方向会有很大差异。直接看以下的比如优先级和劣后级的差异才比较容易了解
四、举个比如
1、打印日志
这儿别离继承于 RelativeLayout、LinearLayout 和 TextView,重写以上三个办法,打印各个办法的回来值,查询其调用机会
类似于这样:
class MyRelativeLayout @JvmOverloads constructor(
context: Conte面试xt,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) :github RelativeLayout(context, attrs, defStyleAttr) {
protected fun log(any: Any?) {
Log.android下载e("MyRelativeLayout", an优先级是什么意思y?.toString() ?: "null")
}
override fun dispatchTouchEvent(event: MotionEvent): Boolean {
when (e优先级最高的运算符vent.ac面试必问10大问题答复tion) {
MotionEvent.ACTION_DOWN -> log("dispatchTouchEvent ACTION_DOWN")
MotionEvent.ACTION_MgiticomfortOVE -> log("dispatchTouchEvent ACTION_优先级排序MOVE")
MotionEvent.AC优先级和劣后级的差异TION_UP -> log("dispatchTouchEvent ACTION_UP")
}
val flag = super.dispatchTouchEvent(event)
log("dispatchTo面试常见问题及答复技巧uchEvent return: $flag")
return flag
}
override fun onInterceptTouchEvent(event: MotionEventgiti轮胎是什么品牌): Boolean {
when (event.action) {
Moti源码买卖网站源码onEvent.ACTION_DOWN -> log("onInterceptTouchEvent ACTION_DOWN")
MotionEvent.ACTION_MOVE -> log("onInterceptTouchEvent ACTION_MOVE")
MotionEvent.ACTION_UP -> log("onIn源码编辑器terceptTouchEvent ACTION_UP")
}
val flag = super.onInterce面试ptTouchEvent(event)
log("onIntgitlaberceptTouchEvent return: $flag")
returnGit flag
}
override fun onTouchEvent(event: MotionEvent): Boolean {
whe源码共享网n (event.action) {
MotionEvent.ACTION_DOWN -> log("onTouchEvent ACTION_D源码超市OWN")
MotionEvent.ACTION_MOVE -> log("onTouchEvent A面试必问10大问题答复CTION_MOVE")
MotionEvent.ACTION_UP -> log("onTouchEv面试毛遂自荐3分钟通用ent ACTION_UP")
}
val flag = super.onTouchEvent(event)
log("onTouchEvent r优先级英文egit指令turn: $f源码超市lag")
return flag
}
}
布局面试的嵌套层次:
<github.leavesc.motion_event面试问题.MyRelativeL优先级和劣后级的差异ayout>
<github.leavesc.motion_event.MyLinearLayout>
<github.leavesc.motion_even面试t.MyTextView/>
</github.legithubavesc.motion面试问题_event.MyLinearLayout>
</github.leavesc.motion_event.MyRandroid什么意思elativeLayout>
点击 TextView 内容区域,打印出来的日志信息:
MyRelativeLayout: dispatchTouchEvent ACTION_DOWN
MyRelativeLayout: onIntercep面试毛遂自荐范文通用tTouchEvent ACTION_DOWN
MyRelativeLayout: onInterceptTouchEvandroid下载软件appent return: false
MyLinearLayout: dispatchTouchE优先级英文vent A源码共享网CTION_DOWN
MyLinearLayout: onInterceptTouandroid界面设计chEvent ACTION_DOWN
MyLinearLayout: onInterceptTouchEvent retuandroid/yunosrn: false
MyTextView: dispatchTouchEvent ACTION_DOWN
MyTextView: onToAndroiduchEvent ACTION_DOWN
MyTextView: oandroid平板电脑多少钱nTouchEvent return: false
MyTexandroid下载软件apptView: dispatchandroid手机TouchEvent retu面试常见问题及答复技巧rn: false
MyLinearLayout: onTouchEv优先级排名是什么意思ent ACTION_DOWN
MyLinearLayout: onTouchEvent return: false
MyLinearLayout: d源码买卖网站源码ispatchT面试问题ouchEvent return: false
MyRelativeLay优先级是什么意思out: onTouchEvent ACTION_DOWN
MyRelativeLayout: onTouchEvent return: false
MyRelativeLayout: dispatchTouchEvent return: false
从以上日志信面试技巧和注意事项息能够总结出:
- 当点击屏幕时,即便当时点击的区域处于 TextView 内,作业分发流程也是从 MyRelativeLayout 这个根 ViewGroup 初步的。源码网站体系会依据接触点来判别手指是落在哪个 ViewGroup 内,然后经过遍历的办法来找到坐标点究竟是落在哪个底面试必问10大问题答复层 View 内部,然后在 ViewGrogitiup 和 View 之间来流通整个作业序列
- 作业分发流程先从根 ViewGroup 从上往下(从外向内)向内源码网嵌的底层 View 传递,即从 MyRelativeLayout 到 Mgithub是干什么的yLinearLayout,再到 MyTextView优先级排序,究竟又反向面试问题大全及答案大全传递从下往上(从内向外)进行传递。这儿说的底层 View 既指 View 类的各种子类,也能够指不包括 View 的 ViewGroup,本文特定指各种非 ViewGroup 类型的 View 子类
- 关于 ViewGroup 来说,源码编辑器编程猫下载其 di源码本钱spatchTouchEvent 办法内部会先调用其 onInterceptTouchEvent 判别是否需求进行阻遏,假定 onIntegitvrceptTouchEvent 办法回来了 false,则意面试技巧味着其不计划阻遏该作业,那么就会持续调用 child 的 dispatchTouchEvent 办法,持续重复以上进程
- 假定面试和面试方式根 ViewGroup 内嵌的悉数 ViewGroup 均不阻遏接触作业的话,那giti轮胎是什么品牌么作业经过循环传递就会分发给最底层的 View
- 关于 View 来说,其不包括 onInterceptTouchEvent源码本钱 办法,dispatchTouchEvent 办法会直接调用其 onTouchEvent 办法来抉择是否消费该接触作业。假定回来 false,则意味着其不计划消费该作业,回来 true 的话则意味着作业被其消费了,间断传android下载软件app递。此刻接触作业现已到了最底层,因为 TextVie优先级超越50预定失利w 默许就是不github是干什么的行点击的,在默许状况下不会消费任何接触作业,因为找不到顾客,所以接着就会优先级英文将作业依次返还给父容器
- MyTextView 不计划消费该接触工android平板电脑多少钱作后,MyLinearLayout 的 onTouchEvent 办法就会接着被调用,之后 MyLinearLay优先级调度算法out 的源码共享网 dispatchTouchEvent 才究竟面试常见问题及答复技巧得到承认的回来值 false。这阐明内部 View 的回调作业是由其父容器 ViewGroup 来担任调用的android什么意思,经过递归调用的办法来完毕整个作业的分发,源码编辑器编程猫下载从 MyRelativeLayout 的 dispatchTouchEvent 办法的回来值是究竟才打印也能够看出来android界面设计
2、Activity 参与作业分发
前文有讲到,每次的接触作业都是从 ACTION_DOWN 初步,以 ACTION_UP 作为完毕的,可是上面的日志信息却只看到了 ACTIandroid体系ON_DOWN,ACTION_UP 去哪了呢?
其实,接触作业的初步分发点应该从 Activity 看起才对,Activity 会早于 ViewGroup 收到接触作业,重写 Activity 的 dispgitiatchTouchEvent 和 onTouchEvent 两个办法,能够得到如下日志:
MotionMainActivity: di面试和面试方式spatchTo源码共享网uchEvent ACTION_android/yunosDOWN
MyRelat优先级 劣后级iveLayout优先级英文: dispatchT优先级和劣后级的差异ouchEvent ACTION_DOWN
MyRelativeLayout: onInterceptTouchEvent ACgiticomfortTION_DOWN
MyRegiteelativeLayo优先级 劣后级ut: onInterAndroidceptTouchEvent return: false
MyLinearLayout: dispatchTouchEvent ACTION_DOW源码超市N
MyLinearLaygiteeout: onInterceptTouchEvent ACTION_DOWN
MyLinearLayout: onInterceptTouchEvent reandroid11turn: false
MyTextView: dispatchTouchEvent ACTION_DOWN
MyText源码编辑器编程猫下载View: onTouchEvent ACTION_DOWN
MyTextView: onTouchEvent return: false
MyTextView: dispatchTouchEvent return源码年代: fals优先级是什么意思e
MyLinearLayout: onTouchEvent ACTIONandroid下载软件app_DOWN
MyLinearLa源码编辑器编程猫下载youtgitee: onTouchEvent return: false
MyLinearLayout: dispatchTouchEvenandroid下载软件appt return: false
MyRelativeLayout: onTouchEvent ACTION_DOWN
MyRelativeLayout: onTouchEvent r面试和面试方式eturn: false
MyRelativeLayout: dispatchTouchEvent return: false
MotionMainActivity: onTgithubouchEvent ACTION_DOWN
MotionMainActivity: onTouchEvent regit指令turn: false
MotionMainActivity: dispatchTouchEvent return: false
Mo面试问题大全及答案大全tionMainActivity: dispatchTouchEvent ACTION_giteeUP
MotionMainActivity: onTouchEvent ACTION_UP
MotionMainActivity: onTouchEvent return: false
MotionMainA面试技巧ctivity: dispatchTgit指令ouchEvent return: false
从Android以上日志信息能够总结出:
- Activity 会早于各个 ViewGroup 和 View 接纳到触android体系摸作业,ViewGroup 和 View 没有消费掉的 ACTION_DOWN 作业究竟仍是会交由 Activi优先级排名是什么意思ty 来消化掉
- 因为 ViewGroup 和 View 均没有消费掉 ACTION_DOWN 工Git作,所以后续的 A面试毛遂自荐3分钟通用CTION_UP 作业不会再持续向它们下发,而是会直接调用 Activity 的 onTouchEvent 办法,由 Activity 来消化掉
3、ViewGroup 阻遏作业
假定 V源码怎样做成app软件iewGroup 自身阻遏且消费了 ACTION_DOWN 作业源码共享网,即 onInterceptTouchEvent 和 onTouchEvent 两个办法均回来了 true,那么本次作业序列的后续作业就都会交由其进源码编辑器行处理(假定能接纳得到的话),不会再调用其 onInterceptTouchEvent 办法来判别是否进行阻遏,dis优先级patchTouchEvent 办法会直接调用 onTouchEvent 办法
而假定 ViewGroup 阻源码超市挠了 ACTION_DOWN 作业,可是 on面试问题大全及答案大全T源码网站ouchEvandroid是什么手机牌子ent 办法中又没有消费掉该作业的话,那么本次作业序列的后续作业都不会再被其接纳到,而是直接交由父视图进行处理。View 对 ACTION面试技巧_DOWN 作业的处理源码网逻辑也是如此
假源码编辑器编程猫下载设悉数的 ViewGroupgitee 和 View 都没有消耗 ACTION_DOWN 作业的话优先级最高的运算符,则后续作业(ACTION_MOVE 和 ACTION_UP 等)都会直接交由 Activity 进行处理, ViewGroup 和 View 没有机会再接触到后续作业
能够改下处于中心层次的 MyLinearLayout 来验证下,onI源码编辑器nterceptTouchEvent 办法接纳到 ACTION_DOWN 作业时直接回来 tru优先级排名是什么意思e
class MyLinearLayout @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr) {
override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
when (eve源码买卖网站源码nt.aandroid界面设计ction) {
MotionEvent.ACTION_DOWN -&gandroid下载t; {
log("onInterceptTouchEvengiteet ACTION_DOWN"gitee)
return true
}
MotionEvent.ACTION_MOVE -> log("onInterceptTouchEvent ACTION_MOVE")
MotionEvent.ACTION_UP ->giti log("onInter源码ceptTouchEvent ACTION_UP")源码怎样做成app软件
}
val flag = super.onInterc面试问题大全及答案大全eptTouchEandroid手机vent(event)
log("onInterceptTouchEvent return: $优先级排名是什么意思flag")android下载
return flag
}
}
此刻 MyLGitinearLa优先级最高的运算符yout面试问题 阻遏了 ACTION_DOWN 作业,所以 MyTextView 不会接纳到该作业。但因为 MyLinearLayo优先级超越50预定失利ut 并没有消费掉该作业,所以 ACTIO源码怎样做成app软件N_DO优先级排序WN 作业仍是会传回面试常见问题及答复技巧给父容器 MyRelativeLayout,而 MyRelativeLayout 默许也是不会消费该作业,所以后续的 ACTandroid什么意思ION_UP 也只会交由 Activity 进行处理
Moti优先级排名是什么意思onMainActivity: dispatchTouchEvent ACTION_android界面设计D面试问题OWN
MyRelati面试必问10大问题答复veLayout: dispatchTouchEvandroid手机ent ACTION_DOWN
MyRelativeLayout: onInte源码本钱rceptTouchEvent ACTION_DOWN
MyRelativeLayout: onInterceptTouchEvent return: false
MyLinearLayout: dispatchTouchE优先级 劣后级vent ACTION_DOWN
MyLinearLayou面试和面试方式t: onInterceptToandroid手机uchEgithubvent ACTIOAndroidN_DOWN
MyLinearLayout: onTouchEvent ACTION_DOWN
MyLinearLayout: onTouchEvent return: false
MyLinearLayout: dispa源码tchTouchEvent return: false
MyRelativeLayout面试技巧: onTouchE源码vent ACTION_DOWN
MyRelativeLayout: onTouch面试必问10大问题答复Event return: false
MyRelativeLayout: dispatchTouchEvent return: false
MotionM源码超市ainActivity: onToucgiticomforthEgiteevent ACTION_DOWN
MotionMainActivity: onTouchEvent面试毛遂自荐3分钟通用 return: false
MotionMainActivity: dispatchTouchgiti轮胎是什么品牌Event return: false
MotionMainActivity: di面试问题spatchTouchEvent优先级 ACTION_UP
MotionMainActivity: onTouchEvent ACTION_UP
MotionMainActivity: onTouchEvent return: false
MotionMainActivity: dispatchTouchEvent return: false
而假定 MyLinearLayout 既阻遏也消费了 ACTION_DOWN 作业,那么仍是能够接纳到后续作业
class MyLinearLayout @JvmOverloads constrandroid11uctor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : LinearLayout(context, attrs,面试和面试方式 defStyleAttr) {
override fun面试必问10大问题答复 onInterceptTouchEvent(event: MotionEvent): Boolean {
when (e源码怎样做成app软件vent.actio优先级排名是什么意思n) {
MotionEvent.ACTION_DOWN -> {
log("onInterceptTouchEvent ACandroid11TION_DOWN")
return true
}
Mgithub中文官网otionEvent.ACTION_MOVE ->优先级排序 log("onInterceptTouchEvent ACTION_MOVE")
MotionEvent.ACTION_UP -> log("onInterceptTouchEvent ACTION_UP")
}
val flag = super.onIntercandroid什么意思eptTouchEvent(event)
log("onInterceptTouchEvent return: $flag")
return flag
}
override fun onTouchEvent(event: MotionEvent): Boolean {
when (event.action) {
MotionEvent.ACTION_DOWN -> {
log("onTouch优先级 劣后级Event ACTION_DOWN")
retur优先级英文n true
}
MotionEvent.ACTION_MOVE -> log("onTouchEvent ACTI源码编辑器ON_M源码网OVE")
MotionEvent.ACTION_UP -> log("onTouchE优先级vent ACTION_UP")
}
val flag = supe源码本钱r.ogithub是干什么的nTouchEvent(event)
log("onToucandroid界面设计hEvent return: $flag")
return flag
}
}
从日志能够看到 MyLinearLayout面试毛遂自荐3分钟通用 接纳到了后续的 ACTION_MOVE 和 ACTION_面试问题大全及答案大全UP 作业,且此刻并没有再次调用 onIandroid平板电脑多少钱nterceptTouchEve源码年代nt 办法,而是直接调用了 onTouchEveandroid什么意思nt 办法
MyRelativeLayout: dispatchTouchEvent ACTION_DOWN
MyRelativeLayout: onInterceptTouchEvent ACTION_DOWN
MyRelativeLayout: on面试技巧和注意事项InterceptTouchEv优先级超越50预定失利ent return: false
MyLinearLayout: dispatchTouchEvent ACTION_源码共享网DOWN
MyLinearLayout: onInterceptTouchEvent ACTION_DOWN
MyLinearLayout: onTouchEvent ACTION_DOWN
MyLinearLayout: dispatchTouchEvent return: true
MyRelativeLayout: dispatchTouchEvent return: true
MyRelativeLayout: dispgit指令atch源码超市TouchEvent ACTIONgiti_MOVE
MyRelativeLayout: onInterceptTouchEvent ACTION_MOVE
M源码怎样做成app软件yRelativeLayout: onInterceptTouchEvent return面试毛遂自荐: false
MyLinearLayout: dandroid下载ispatchTouchEvent ACTION_MOVE
MyLinearLayout: onTouchE优先级排序vent ACTION_MOVE
MyLinearLayout: onTouchEvent return: false
MyLinearLayout: dispatchTouchEvent源码共享网 return: false
MyRelativeLayout: dispatch面试问题TouchEvent return: false
MyRelatiandroid是什么手机牌子veLayout: dispatchTouchE源码超市vent ACT源码网站ION_UP
MyRelativeLayout: onInterceptTouchEvent ACTION_UP
MyRelativeLayout: onIntgitierceptTouchEvent return: false
MyLinearL优先级是什么意思ayout: dispatchTouchEvent ACTION_UP
MyLinearLayout: onTouchEvent ACTION_UP
MyLinearLayout: onTouchEvent return: false
MyLinearLayoutAndroid: dispatchTouchEventgit指令 return: false
MyRelativeLayout: dispatchTouchEvent return: false
此外,有一个需求留神的点是,即便每个 ACTION_MOVE 作业 MyLinearLayout 均没有消优先级行列费掉,MyLinearLayout 相同能够无缺接纳到整个作业序列的音讯,且此刻父容器的 onTouchEvent 办法也不会被回调。因为在正常状况下,一个作业序列只应该由单独一个 View 或许 ViewGroup 进行处理,已然 MyLinearLayo源码怎样做成app软件ut 现已消费了 ACTandroid手机ION_DOWN 作业,那么后续的作业应该也都交由其进行处理
4、View 消费作业
Vigiticomfortew 没有阻遏工github作这个进程,但假定有消费掉 ACTION_DOWN 作业的话giticomfort,后续作业就都能够接纳到
clgithub是干什么的ass MyTextView @J源码编辑器vmOverloads construcandroid/yunostor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : AppCompatTextView(context, attrs, defStyleAttr) {
override fun onTouchEandroid是什么手机牌子vent(event:面试技巧 MotionEvent): Boolean {
when (event.action) {
MotionEvent.A源码编辑器编程猫下载CTION_DOWN -> {
log("ongiti轮胎是什么品牌TouchEvent ACTIONandroid/yunos_DOWN")
return true
}
MotionEv优先级ent.ACTION_MOVE -> log("onTouchEvent ACTION_MOVE"面试问题大全及答案大全)
MotionEvent.ACTION_UP -> log("onTouchEvent ACTION_UPandroid什么意思")
}
val flag = super.onTouchEvent(event)
log("onTouchEvent return: $flag")
return flag
}
}
能够看到,MyTextView 接纳到了面试毛遂自荐范文通用后续的 ACTION_MOVE 和 ACTION_UP 作业
MyRelati源码编辑器veLayout: dispatchTouchEvent A面试技巧CTION_DOWN
MyRelativeLayout: onInt面试问题大全及答案大全erceptToucandroid界面设计hEvent ACTION_DOWN
MyRelativeLayout: onInandroid11tgithub中文官网erceptTouchEvent return源码本钱: false
MyLgithubinearLayout: dispatchTouchEvent ACTION_DOWN
MyLinearLayout: onInterceptTouchEvent ACTION_DOWN
MyLinearLayout: onInterceptTouchEvent return: false
MyT源码网extViandroid手机ew: dispatchTouchEvent ACTION_DOWN
MyTextVgithub是干什么的iew: onTouchEvent ACTION_DOWN
My优先级行列TextView: dispatchTouchEvent return: true
MyLinearLayout: dispatchTouchEvent return优先级最高的运算符: true
MyRelativeLayout: dispatchTouchEvent return: true
MyRelativeLayout: dispatchTouchEvent ACTION_MOVE
MyRelativeLayout: onInterceptT源码编辑器编程猫下载ouchEvent ACTION_MOVE
MyRelativeLayout: on优先级英文InterceptTouchEvent return: false
MyLinearLayout: dispatchTouchEvent ACTION_MOVE
MyLinearLayout: onInterceptTouchEvent AC优先级排序TION_MOVE
MyLinearLayout: onInterceptTouchEv源码年代ent return优先级超越50预定失利: fagitilse
MyTextView:源码超市 dispatchTouchEvent Aandroid是什么手机牌子CTION_MOVE
MyTextView: onTouchEvent ACgiticomfortTION_MOVE
MyTextView: onTouchEvent return: false
MyTextView: dispatchTouchEvent return: false
MyLi优先级超越50预定失利nearLayout: dispatchTouchEandroid下载软件appvent return: false
MyRel面试毛遂自荐3分钟通用ativeLayout: dispatchTouchEvent return: false
MyRelativeLayout: dispatchTouchEvent ACTION_UP
M源码超市yRelativeLayout: onI面试必问10大问题答复nterceptTouchEvent ACTION_UP
MyRel面试问题ativeLayout: onInterceptTouchEvent return: false
MyLinearLayout: dispatchTouchEvent ACTI源码买卖网站源码ON_UP
MyLinearLayout: onInterceptTouchEvent ACTION_UP
MyLinearLayout: onInterceptTouchEventgiticomfort return: false
MyTextView: dispatchTouchEvent ACTION_UP
MyTextView: onTouchEvent ACTION_UP
MyTextView: onTouchEvent return: false
MyTextView: dispatchTgitvouchEvent returgiticomfortn: fal优先级 劣后级se
MyLinearLayout: dispatchTouchEvent return: false
M优先级yRelativeLayout: dispatchTou面试常见问题及答复技巧chEvent return: false
和上面一个比如相同。即便每个 ACTION_MOVE 作业 MyTextView 均没有消费掉优先级排序,MyTextView 相同能够无缺接纳到整个作业序列的音讯,且此刻面试技巧父容器的 onTouchEvent 办法也不会被回调,整个作业优先级调度算法序列都只交Git由 MyTex面试问题tView 来处理了
咱们也能够经过修改代码来使得上层 ViewGroup 自动阻遏后续作业,但这也会导致一些问题,因为假定 MyTextView 没有接纳到 ACTION_UP 作业的Git话,会导致其 OnClickListener 无法被回调
总的优先级行列来说,View 是否能接纳到整个作业序列的音讯首要就取决于其是否消费了 ACTION_DOWN 作业,ACTION_DOWN 作业是整个作业序列的初步点,View 必源码超市须消耗了初步作业才有机会无缺处理整个作业序列
五、总android什么意思结
- Activity面试毛遂自荐 会早于各个 ViewGroup 和 View 接纳到接触作业,Activity 能够经过自动阻遏掉各个作业的下发使得 ViewGroup 和 View 接纳不到任何作业。而假定 ViewGroup 和 View 接纳到了 ACTION_DOWN 作业但没有消费掉,那么作业究竟仍是android11会交由 Activity 来消费
- 当接触作业被触发时,体系会依据接触点优先级英文的坐标系找到根 ViewGroup,然后向源码编辑器底层 View 下发作业,即作业分发流程先是从根 ViewGroup 从上往下(android是什么手机牌子从外向内)向内嵌的底层 View 传递的,假定在这个进程中作业没有被消费的话,究竟又会反向传github中文官网递从下往上(从内向外)进行传giticomfort递
- ViewGroup 在接纳到 ACTIgithubON_DOWN 作业时,其 dispatchTouchEvent 办法内部会先调用 onInterceptTouchEvent 判别是否要进行阻遏,假定 onInterceptTouchEvent 办法回来了 false,则意味着其不计划阻遏该作业,那么就会持续调用 child 的 dispatchTouchEvent 办法,持续重复以上进程。假定阻遏了,那么就会调用 onToucgithubhEvent 进行消费
- 假定 ViewGroup 自身阻遏且消费了 ACTION_DOWN 作业,那么本次作业序列的后续作业就会都交由其进行处理(假定能接纳得到的话),不会再调用其 onInterceptTouchEvent 办法来判别是否进行阻遏,也不会再次遍历 child,dispatchTouchEvent 办法会直接调用 onTouchEvent 办法。这源码怎样做成app软件是为了尽量防止无效操作,行进体系的制造功率
- 假定面试常见问题及答复技巧根 ViewGroup 和内嵌的悉数 ViewGroup 均没有阻遏 ACTION_DOWN 作业的话,那么作业经过循环传递就会分发给最底层的 View。关于 View 来说,其不包括 onInte优先级行列rceptTouchEvent 办法,dispatchTouchEven面试技巧和注意事项t 办法会调用其 onTouchEvent 办法来抉android手机择是否消费该作业。假定回来 false,则意味着其不计划消费该作业,作业将依次调用父容器的 onTouchEvent 办法;回来 tr源码共享网ue 的话则意味着作业被其消费了,作业间断传递
- 而不论 Vi源码本钱ewGroup 有没有阻遏 ACTION_DOWN 作业,只需其自身和悉数 child 均没有消费掉 ACTION_DOWN 作业,即 dispatchTouchEvent 办法回来了 falAndroidse,那么此 ViewGroup 就不会再接纳到后续作业面试必问10大问题答复,后续作业会被 Activity 直接消化掉
- 而不论是 ViewGroup 仍是 View,只需其消费了 ACTION_DOW优先级调度算法N 作业,即便 onTouchEvent 办法在处理每个后续作业时均回来了 fa源码lse,都仍是能够无缺接纳到整个作业序列的音讯。后续作业会依据在在处理 ACTION_DOWN 作业保存的引证链,从上源码买卖网站源码往下依次下发
- View 是否能接纳到整个作业序列的音讯首要就取决于其是否消费了 ACTION_DOWN 作业,ACTION_DOWN 作业是整个作业序列的初步点,View 有必要消耗了初步作业才有机会无缺处理整个作业序列
- 处于上游的 ViewGroup 不关心到底是轻贱的哪个 ViewGroup 或许 View 消费了接触作业,只需轻贱的 dispatchTouchEvent 办法回来了 true,上游就android下载会持续向轻贱下发后续作业
- ViewGroup 和 View 关于每次作业序列的消费进程是独立的,即上一次作业序列的消费效果不影响新一次的作业序列
六、View
View 是 Android 整个体系最根底的gitv基类之一,这儿面试毛遂自荐来对 View 的作业分发源码做下剖面试技巧析,以此来验证上边我给出的定论,依据 SDK 30 版别进行剖析
dispatchTouchEvent
View 的 disandroid是什么手机牌子patchTouchEvent 办法逻辑上还比较简略,能够总结为:
- 对应第一步。假定 View 是 ENABLED 状况,既处于可用情android体系况,且当时是经过鼠标设备输出的 ScrollBarDragging 作业并被处理了,那么就阐明其android体系时 View 消耗了本次接触作业
- 对应第二步。假定 View 是 ENAgithubBLED 状况,且android11此刻外部设置的 OnTouchLis面试问题tener 回来了 true,那么就阐明当时 View 交由外部消耗了本次接触作业
- 对应第三步。假定以上几步均不建立,那么就会再调用 onTouchEvent 办法,假定该办法回来了 true,那么也阐明当时 View 消耗了本次接触作业
- 所以说,外部设置的 OnTouchListener 的优先级会高于自身的 onTouchEvent 办法,OnTouchListener 能够依托回来值使得 onTouchEvent 办法优先级行列不被调用
public boolean dispatchTouchEvent(MotionEvent event源码网站) {
//用于标明当时 View 是否消费了该作业优先级 劣后级
boolean result = false;
final int actionMasked = event.getActionMasked();
if (onFilterTouchEventForSecurity(eventgiti)) {
//第一步
if ((mViewFlags & ENABLED_MASK) == ENABLED && handleScrollBarDragging(event))android平板电脑多少钱 {
result = true;
}
//第二步
Lisgithub中文官网t面试enerInfo li = mListenerInfo;
if (li != null && li.mOnTouchListener != null
&& (mViewFlags & ENABLED_MASK) == ENABLED
&& li.m源码网站OnTouchListener.onTouch(this, event)) {
result = true;
}
//第三步
if (!result &android下载软件appamp;& on优先级是什么意思TouchEvent(event)) {
result = true;
}
}
return resugithublt;
}
onTouchEvent
onToucgitihEvent 办法就比较杂乱了,咱们只看其骨干思路即可,能够总结Git为Git:
- 对应第一步。假定当时 View 处于禁用 DISABLED 状况,且当时是可点击 cliandroid平板电脑多少钱ckab面试问题le 状况,即 CLICKABandroid下载软件appLE、LONG_CLICKABLE、CONTEXT_CLICKABLE 这三个条件至少有一个满意的gitv话,那么就回来 true。这三个条件别离对应着:可点击、可长按点击、可上下文点击
- 对应第二步。假定 TouchD源码买卖网站源码elegate 存在且消耗了触优先级排名是什么意思摸作业,那么就源码网回来 true
- 对应第三步。假定当时处于 cli优先级行列ckable 状况或许
(viewFlags & TOOLTIP) == TOOLTIP
建立的话,那么也会消耗当时作业。TO面试问题OLTIP 能够经过添加android:tooltipText="tips"
来翻开,翻开后长按 TextView 会闪现一个悬浮窗办法的提示文本 - 对应第四步。android是什么手机牌子onToucgit指令hEvent 内部在接纳到 ACTION_UP 作业的时分,会判别是否回调外部设置的 OgithubnClickListener,因而假定外部设置的 OnTouchListener 回来了 true,那么 OnClickListener 就不会被回调。这也导致gitlab了假定上层视图消耗了 ACTION_UP 作业的话,OnClickListener 就不会被回调
public boolean onTouchEvent(MotionEvent event) {
final boolean cl优先级最高的运算符ickable = ((viewFlags & CLICKABLE) == CLICKABLE
|| (viewFlagiteegs & LONG_CLICKABLE) == LONG_CLICKABLE)
|| (viewFlags & CONTEXT_CLICKABLE) == CONTEXT_CLICgit指令KABLE;
if ((viewFlags & ENABLED_MASK) == DISABLED) {
//第面试一步
return clickable;
}
//第二步
i源码买卖网站源码f (mTouchDelegate != null) {
if (mTouchDelegate.onTouchEvent(event)) {
return true;
}
}
//第三步android下载软件app
if (clickable || (viewFlags & TOOLTIP) == TOOLTIP) {
if (!fo优先级行列cusTaken) {
if (mPerformCandroid体系lick == nu面试技巧ll) {
mPerformClick = new PerformClick();
}
if (!pandroid11ost(mPerformClick)) {
//第四步
performClickInternal();
}
}
return true;
}
return false;
}
所以说,dispatchTouchEvent 内部的确是会调用 onTouchEvent 办法,且假定 View 处于可面试问题大全及答案大全点击状况的话,那么就会消耗该接触作业,且 OnClickListener 是在 onTouchEvent 办法中被调用的
举个比如。TextView 默许是不可点击状况,而 Button 是直接承优先级调度算法继于 TextView 的,因而 Button 默许状况也是不可点击且不会消耗任何接触作业的,而 Button 之所以在咱们日常运用进程中会消耗掉接触作业,是因为往往咱们都会为其设置 On面试毛遂自荐3分钟通用ClickListener,此刻就会将 Button 的giticomfort Clickable 置为 true
public void setOnClickListene面试问题大全及答案大全r(@Nullab优先级 劣后级le OnClickListener l) {
if (!isClickable()) {
sgiticomfortetClickable(true);
}
getListenerInfo().mOnCligitlabckListener = l;
}
七、ViewGroup
ViewG优先级排序roup 直接继承于 View,其逻辑是在 View 的根底上来做扩展的,这儿就直接看 ViewGroup 类是如何来结束上述介绍的三gitlab个办法的
dispatchTouc优先级英文hEventandroid下载软件app
ViewGroup 的 dispatchTouchEvent 办法相对 View 就要杂乱许多了,因为 Viegithubw 在整个视图体系中处于源码超市最根底的底层,只需求处理好自己就能够,而 ViewGroup 还需求处理其内嵌的布局,或许源码网站会包括多个子 ViewGroup 和子android界面设计 View
该办法的首要流程能够总源码共享网结为:
- 对应第一步。假定当时接纳到的是 ACTION_DOWN 作业,阐明是一次新的作业序列,则清除掉 mFirstTouchTarget 的引证。在每次作业序列中,假定 child 消费了 ACTION_DOWN 作业,那么 ViewGroup 就会经过 mFirstTouchTarget 来指向 child,后续作业就能够经过该引证来直接传递而不需再次进行遍历
- 对应第二步。此android手机进程用来判优先级是什么意思别是否要阻遏作业。假定 if 条件建立,阐明当时处理的是新的一次作业序列或许是 ACTION_DOWN 之后的作业且之前的 ACTION_DOWN 现已被 child 消费了,那么就经过调用 onInterceptTouchEvent 办法来抉择是否阻遏。而假定 chil源码怎样做成app软件d 自动经过调用
mParent.requesgit指令tDisallowInterceptTouchEvent
央求当时 ViewGrou源码超市p 不进行阻遏的话(既 disallowIntercandroid下载ept 为 true),那么就直接将 intercepted 置为 false,不进行阻遏。这就说清楚,除非 child 自动要github求 ViewGroup 不阻遏,不然归于 child 的作业序列父布局都仍是有机会进行阻遏的 - 在第二步中,需求留神 ACTION_DOWN 作业不受 FLAG_DISALLOW_INTERCEPT 这个符号的控制,即 child 无法自动阻止 ViewGro面试毛遂自荐3分钟通用up 不阻遏 ACTION_DOWN 作业,ViewGroup 的 onInterceptTouchEvent 办法依然会被调用
- 在第优先级调度算法二步中,假定 ViewGroup 在接纳到 ACTION_DOWN 的时分进行了阻遏,那么 mFirstTouchTarget 就不会被赋值,这也导致了在接纳后续作业时 if面试常见问题及答复技巧 句子不建立,这样在整个作业序列中 onInterceptToucandroid界面设计hEvent 办法只会实施优先级 劣后级一次,这也是上文给出的总结内容之一
- 对应第三步。ACTION_DOWN 作业源码买卖网站源码会走到这儿面试,因为当时 inte优先级排名是什么意思rcepted 为 false,即不阻遏作业,因github是干什么的此此刻就会去遍历 children,判别接触点坐标系是落在哪个 child 内,找得到的话就用 mFirstTouchTarget 指向该 child
- 对应第四步。此刻 mF面试毛遂自荐范文通用irstTouchTarget 为 null,阐明 ViewGroup 没有找到下一个能够接纳作业的 child源码,也许是没有 child,也许是 child 均不处理该giticomfort作业,也或许是 ViewGroup 自己阻遏了该作业,那么就将当时 ViewGroup 作为一个一般的 View 子类,经过调用 dispatchTransformedTouchEvent 办法来实施父类 View 的 dispatchTouc面试问题大全及答案大全hEvent 办法,依照原始的 View 分发逻辑进行实Android行。因而 ViewGroup 在自动阻遏作业后就会去调用 onTouchEvent 办法
- 在第四步中,假定此 ViewGroup 究竟消费优先级和劣后级的差异了该作业,那么在接纳到后续作业的时分,此刻 mFirs优先级最高的运算符tTouchTarget 没有指向 child,仍是为 null,所以就会直接走第二步的 else 句源码网子,然后不去遍历 childregit指令n。这就意味着后续作业既不会回调 onInter源码网站ceptTouchEvent 办法,也不会去遍历 child,这也是上文给出的总结内容之一
- 对应第五步。此刻 mFirstTouchTarget 不为 null,那么就会去调用 child 的 dispatchTouchEvent 办法,重复以上进程,然后得知 child 对该作业的处理效果 handled
- 所面试问题以说,ViewGroup 经过这种递归调用,究竟就会github是干什么的为上层视图 Activity源码编辑器 回来毕giti竟的作业处理android是什么手机牌子效果
@Overriandroid下载de
public源码年代 boolean dispatchTo优先级英文uchEvent(Mo源码超市tionEvent ev) {
boolean handled = false;
if (onFiandroid是什么手机牌子lterTouchEvent优先级 劣后级ForSecurity(ev)) {
final int act源码网站ion = ev.getAction();
final int actionMasked = action & MotionEvent.ACTION_MASK;
//第一步
if (actionMasked == MotionEvent.ACTION_DOWN) {
cancelAndClear优先级英文TouchTargets(ev);
resetTouchState();优先级是什么意思
}
//第二步
final boolean intercepted;
iGitf (actionMasked == MotionEvent.ACgit指令TION_DOWN
|| mFirstTouchTarget != null) {
final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTgitlabERCEPT) != 0;
iandroid体系f (!disallowIntercept) {
intercepted = onInterceptTouchEvent(ev);
ev.setAction(action);
} else {
int优先级 劣后级ercepted面试问题大全及答案大全 = fals优先级超越50预定失利e;
}
} else {
intercepted = true;
}
if (!面试毛遂自荐canceled && !intercepted) {
View childWithAccessibilityFocus = ev.isTargetAccessibilityFocgit指令us()
? findChildWithAccessibiligit指令tyFocus() : null;
if (actionMasked == MotionEvent.ACTION_DOWN
|| (split &a源码编辑器编程猫下载mp;& actionMandroid界面设计asked == MotionEvent.ACTandroid下载ION_源码本钱POINTER_DOWN)
|| actionMasked == Moandroid11tionEvent.ACTION_HOVER_MOVE) {
final int actionIndex = ev.getActionIndex(面试技巧和注意事项); // always 0 for down
final int idBitsToAssign = spl面试技巧和注意事项it ? 1 << ev.getPointerId(actionIndex)
: TouchTar源码编辑器get.ALL_POINTER_IDS;面试技巧和注意事项
// Clean up earlier touch targets for this pointer id in case they
// have become out of sync.面试常见问题及答复技巧
removePointersFromTouchTargets(id优先级排序BitsToAandroid/yunosssign);
//第三步
final int childrenCount = mC面试问题大全及答案大全hildrenCount;
if (newTouc优先级超越50预定失利hTarget == null && childrenCount != 0) {
final View[] ch优先级 劣后级ildren = mChildandroid什么意思ren;
for (int i = childrenCount - 1; i >= 0; i--) {
}
}
}
}
}
ifandroid平板电脑多少钱 (mFirstTouchTarget == null) {
//第四步
handled = dgithub中文官网ispatchTransformedTouchEvent(ev, canceled, null,
TouchTarget.ALL_POI源码NTER_IDS);
} else {
//第五步
TouchTarget predecessor = null;
TouchTarget target = mFirstTouchTarget;
while (target != null) {
final TouchTarget next = targgitiet.next;
if (alreadyDispatchedToNewTouchTarget && ta源码本钱rget == newT源码买卖网站源码ouchTarget) {
handled = true;
} else {
final boolean cancelChild = resetCancelNextUpFlag(tAndroidarget.child)
|面试毛遂自荐3分钟通用| intercepted;
if (dispatchTransformedTouchEvent(ev, cancelChild,
target.child, target.pogiti轮胎是什么品牌interIdBits)) {
handled = true;
}
if (cancelChild) {
if (predecessoGitr == null) {
mFirstTouchTarget = next;
} el源码se {
preGitdecessor.next = next;
}
target.recycle(面试毛遂自荐);
target = next;
continu面试毛遂自荐范文通用e;
}
}
predecessor = targ面试毛遂自荐et;
target = next;
}
}
}
if (!handled && mInputEventConsistencyV优先级 劣后级erifi源码网站er != null) {
mInputEventConsistencyVerifier.onUnhandroid11andledEvent(android平板电脑多少钱ev, 1);源码
}
return handled;
}
onInterceptTouc面试和面试方式hEvent
onInterceptTouchEvent 办法只在特定几种状况下才会回来 true,建立条件似乎是当存在外置鼠标设备的时分才有或许建立,读者只需求记住该办法默许回来 false 即可,既默许不进行giti阻遏
public boolean优先级超越50预定失利 onInterceptTouchEvent(MotionEvent ev) {
if (ev.isFromSource(InputDevice.SOURCE_MOUSE)
&& ev.getAction()github是干什么的 == MotionEvent.ACTION_DOWN
&& ev.isButtonPressed(MotionEvent.BUTTON_PRIMARY)
&& isOnScrollbarThumb(ev.getX(), ev.getY())) {
return true;
}
return false;
}
onTouchEvent
ViewGroup 没面试必问10大问题答复有重写其父类 View 的 onTouchEvent 办法,所以此办法和 View 类的逻辑保持一致
八、Activity、PhoneWindow、DecorView
上文在许多当地都讲到了 Activity 会参与 View 的作业分发机制,而实践上除了 Activity 外,这个进程还包括 PhoneWindow 和 DecorView,仅仅这两个都被包括在 Activity 内部,日常开发中一般都面试毛遂自荐范文通用不会接触到这一块。这儿就再来介绍下这三者的效果
- 每个 Activity 都对应一个 PhoneWindow,即每个 Activity 实例均包括了一个 PhoneWindgitlabow 实例
- 每个 PhoneWindow 都对应一个 DecorView,DecorView 依托 PhoneWindow 作为结构参数之一来实例化
- DecorView 是 FrameLayout 的子类,是 Activity 视图树的根视图,咱们往常调用 setContentView 所添加的 View 就对应 De优先级是什么意思corView 的 ContentParent 区域
- 在这三者中 DecorView 会最早接纳到接触作业,DecorView 作为视图树的根视图,就担任向其内部 View 下发接触作业
DecorView 的 d面试和面试方式ispatchTouchandroid体系Event 办法会拿到 PhoneWindow 内含的 Window.Callback 政策优先级行列向其转发作业,而这儿的 Window.Callback 实践上就对应面试毛遂自荐的是 A源码买卖网站源码ctivity,Activity 结束了 Window.Callback 接口
pu优先级行列blic class Dec优先级调度算法orView extends FrameLayout implements RootViewSurfaceTaker, WindowCallbacks {
public boolean supgitierDispatchTouchEvent(MotionEvent event) {
return super.di优先级超越50预定失利spagit指令tchTouchEvent(event);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
final Window.Callback cb = mWindow.getandroid手机Callback();
return cb != null &a面试问题大全及答案大全mp;& !mWindow.isDestroyed() && mFeatureId < 0
? cb.dispatchTouchEvent(ev) : super.dispatchTouchEvent(ev);
}
@Overrideandroid什么意思
public boolean onInterceptToandroid平板电脑多少钱uchEventandroid界面设计(MotionEvent event) {
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return onInterceptTouchEvent(event);
}
}
Activity 的 dispatchTou面试chEvent 和 onTouchEvent 两个办法逻辑都比较简略,在接纳到作业的时分都会源码年代判别优先级是什么意思 PhoneWindow 是否要消费该作业,要的话则直接优先级和劣后级的差异交由其处理,不然默许不消费任何作业。源码网站此外 Activity 也供应giticomfort了源码超市一个空结束的优先级超越50预定失利 onUserInteraction 方面试毛遂自荐范文通用法,向子类供应了 ACTION_DOWN 作业的触发告知
public class Activity {
private WGitindow mWindow;
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEven源码共享网t.ACTION优先级排名是什么意思_DOWN) {
onUserInteraction();
}
if (ge优先级和劣后级的差异tWindow().superDispatchTo面试技巧和注意事项uchEvent(ev源码共享网)) {
return true;
}
return onTouchEvengithub中文官网t(ev);
}
public void onUserInteraction() {
}
publ面试问题大全及答案大全ic boolean onTouchEvent(MotionEvent event) {
if (mWindow.shoul面试dCloseOnTouch(this, event)) {源码本钱
finish();
re面试毛遂自荐3分钟通用turn tru源码共享网e;
}
return false;
}
}
PhoneWindow 是 Window 这个抽象类的仅有结束类,PhoneWindow 又将对应的作业面试技巧交给了 DecorView
public class PhoneWindow extends Window implements MenuBuilder.Callback {
private DecorView mDecor;
@Overri源码编辑器编程猫下载de
public boolean superDispatchTo优先级英文uchEvent(MotionEvent event) {android平板电脑多少钱
return mDecor.superDi源码网站spatchTouchEvent(event);
}
}
再回过头看 DecorView。DecorView 的 superDispagiteetchTouchEvent 办法直接就调用了父类的 dispatchTouchEvent 办法
public class DecorView extends FrameLayout implements RootViewSurfaceTaker, WindowCallbacks {
publ优先级ic boolean sup面试问题erDispatchTouc优先级排序hEvent(MotionEvent event) {
return supeGitrgiti.dispatchTouc源码网hEvent(event);
}
@优先级调度算法Override
public boolean dispatchTouchEvent(MotionEvent ev) {
final Window.Callback源码本钱 cb = mWindow.getCallback();
return cb != null && !mWindo优先级超越50预定失利w.isDestroyed() && mFeatureId < 0
? cb.dispatchTouchEvent(ev) : super面试毛遂自荐3分钟通用.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
}
@Override
public boolean onTouchEvent(优先级超越50预定失利MotionEvent event) {
return onInterceptTouchEvent(event);
}
}github
这三者之间的联络又是怎样的呢?这样兜兜转转一圈,其实就是 Decoandroid界面设计rView 先将作业传给了 Activity,Activity 又传给了 PhoneWindow,PhoneWindow 又将作业传给了 DecorView,DecorView 究竟又依照 ViewGroup 默许的办法进行工android界面设计作分发,看起来就是在绕圈,这样规划的意义是什么呢?面试毛遂自荐
其实,DecorViandroid手机ew 作为接触作业的第一个接纳者,是接触作业从体系下发到源码网 Activity 之间的一个沟通桥梁,而开发者能够直接接触并继承的是 Activity。DecorVie优先级英文w 需求先将作业转优先级超越50预定失利发给最外层的 Activity,使得开发者能够经过重写 dispatchTouchEvent 和 onTouchEvent 办法以达到对当时屏幕接触作业进行阻遏的意图。Dandroid11ecorView 作为 View 树的根节点,从 PhoneWindow 接纳到作业后,又担任android11将将作业作业分发给子 View,然后将整个作业链给串联了起来
因而,这三者之间的作业流通机制,能够说是为了给开发者一个能够进行大局作业阻遏的机会
九、滑动抵触
假定父容器和子 View 都能够照顾滑动作业的话,那么就有或许发生滑动抵触的状况。处理滑动抵触的办法大致上能够分为两种:外部阻遏法 和 内部阻遏法
1、外部阻遏法
父容器依据实践状况在 onInterceptTouc面试和面试方式hEvent 办法中对接触作业进行挑选性阻遏,假面试设判别到当时滑动作业自己需求,那么就阻遏作业并消费,不然就交由子 View 进行处理。该办法有几个留神点:
- ACTION_DOWN 工github作父容器不能进行阻遏,否android什么意思则依据 View 的作业分发机制,后续的 ACTION_MOVE 与 ACTION_UP 作业都将默许交由父容器进行处理
- 依据实践面试必问10大问题答复的业务需求,父容器判别是否需面试技巧求处理 ACTION_MOVE 作业,假定需求处理则进行阻遏消费,不然交由子 View 去处理
- 原则上 ACTION_UP 作业父容器不应该进行阻遏,不然子 View 的 onCligiti轮胎是什么品牌ck 作业将无法被触发
伪代码:
ovegit指令rride fun onIntercep面试tTouchEvent(event: MotionEvent): Boolean {
var intercepted = false
when (event.action) {
MotionEvent.ACTION_DOWN ->android手机; {
intercepted = false
}
MotionEvengiticomfortt.ACTION_MOVE -> {
intercepted = if (满意阻遏要求) {
true
} else {
false
}
}
MotionEvent.ACTION_UP -> {
intercepted = false
}
}
return intercepted
}
2、内部阻遏法
内部阻遏法android平板电脑多少钱则是要求父容器不阻遏任何作业,悉数作业都传递给子 View,子 View 依据实践状况判别是自己来消费仍是传android平板电脑多少钱回给父容器进行处理。该办法有几个留神点:
- 父容器不能阻遏 ACTION_优先级和劣后级的差异DOWN 作业,不然后续的接触作业子 View 都无法接纳到
- 滑动作业的舍取逻辑放在子 View 的
dispatchTouchEvent
办法中,假定父容器需求处理作业则调用parent.re面试问题questDisallowInterceptTouchEvent(false)
办法让父容器去阻遏作业
伪代码:优先级超越50预定失利
子 View 修改其 dispatchTouchEvent 办法,依据实践需求来控制是否答应父容器阻遏作业
override fun优先级英文 dispatchTouchEvent(event: MotionEvent): Bandroid手机oolean {
when (event.aandroid体系ction) {
MogiteetionEvent.ACTION_DOWN -> {
//让父容器不阻遏 ACTION_DOWN 的后续作业
parent.requestDisallowInterceptTouchEvent(true)
}
MotionEvent.ACTION_MOVE -> {
if (父容器需求此作业) {
//让父源码年代容器阻遏后续作业
parent.requestDisallowInterceptTouchEvent(false)
}
}
MotionEvent.ACTION_UP -> {
}
}
return super.dispatchTouchEvent(event)
}
因为 ViewGroup 的 disp优先级atchTouchEvent 办法会预先判别子 View 是否有要求其不阻遏作业,假定没有的话才会调用自身的 onI面试技巧nterceptTouchEvent 办法,所以除了 ACTION_DOWN 外,假定子 View 不阻遏的话那么 Vi面试问题大全及答案大全ewGroup 都进行阻遏
override fun onInterceptandroid体系TouchEvent(even面试毛遂自荐3分钟通用t: Motio源码年代nEvent): Boolean {
return event.acti面试毛遂自荐3分钟通用on != MotionEvent.ACTION_DOWN
}
十、处理滑动抵触
我常常会在网面试和面试方式上看到一些开发者在问怎样处理 Scr源码编辑器ollView 嵌套 ScrollView 后内部 ScrollView 无法滑动的问题,有这问题就是因为发生了滑动抵触,根本原因就是因为用户的面试问题大全及答案大全滑动操作都被外部 ScrollView 阻遏并消费了,导致内部 ScrollView 一向无法照顾滑动作业。这儿就以 ScrgiticomfortollView 嵌套 ScrollView 的状况作为比如,来看看怎样处理它们之间的滑动抵触问题
页面布局如下所示,内部的 ScrollView 是无法单独滑动的,只能跟着外部 ScrollView 一同上下滑android下载软件app动
<?xml version优先级 劣后级="1.0" encoding="utf-8"?>
<Scrogithub中文官网llView xmlns:android="http://sch优先级超越50预定失利emas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
an源码网站droid:layout_height="wrap_content"
android:orientation="vertical">
<include layout="@layout/item_content_a" />
<include layout="@layout/item_content_a" />
<include layout="@layout/item_优先级 劣后级content_a" />
<include layout="@layout/item_content_a" />
<include layout面试问题="@layout/item_content面试毛遂自荐范文通用_a" />面试问题大全及答案大全;
<include layout="@layout/itgithubem_content_a" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="200dp">
<LinearLayout
android:layout_width="match_parent"android是什么手机牌子
android:layout_height="wrap_content"
android:orientation="vertical">
<include layout="@android界面设计layout/item_c优先级行列ontent_b" />
<include layout="@layout/item_content_b" />
<gitv;include layout="@layout/item_content_b" />android下载软件app;
<include layout="@layout/item_content_b" />
<inclu源码编辑器编程猫下载de layout="@layout/item_content_b" />
<include layout=源码编辑器编程猫下载"@layout/item_c面试和面试方式ontent_b" />
</LinearLayo面试毛遂自荐ut>
</ScrollView>
<in优先级英文cludgitlabeandroid是什么手机牌子 layout="@laandroid下载软件appyout/ite优先级排名是什么意思m_content_a" />
<include layout="@layout/item_content_a" />gitee
<include layout="@layout/item_content_a" />
<include layout="@android下载软件applayout/item_conte优先级是什么意思nt_a" />
&l源码怎样做成app软件t;源码怎样做成app软件include layout="@layout/item_content_a" />
<in优先级 劣后级clude layout="@layout/item_content_a" />
</LinearLayout>
</ScrollView>
这儿挑选运用内部阻遏法来处理问题。首要需求让外部 ScrollView 阻遏 ACTION_DOWN 之外的任优先级超越50预定失利何作业
class面试毛遂自荐3分钟通用 ExternalSc优先级调度算法rollViegiti轮胎是什么品牌w @JvmOverloads constructor(
context: Context, attrs: Attribute面试和面试方式Set? =优先级排序 nu源码怎样做成app软件ll, defgitvStyl面试技巧e面试毛遂自荐Attr: Int = 0
) : ScrollView(优先级最高的运算符context, attrs, defStyleAttr) {
overr优先级和劣后级的差异ide fun onIntercep面试和面试方式tTouchEvent(motionEvent: MotionEvent): Boolean {
val intercepted: Boolean
when (giteemotionEvent.action) {
MotionEvent.ACTION_D源码编辑器编程猫下载OWN -> {
intercepted = false
super.onIn面试terceptandroid下载TouchEvent(motionEvent)
}
else -> {
intercepted = true
}
}
return intercepted
}
}
内部 ScrollView 判别自身是否还处于可滑动状况,假定滑动到了最顶部还想再往下滑动,或许是滑动到了最底部还想再往上滑动,那么就将作业都交由外部 ScrollView 处理,其它状况都直Git接阻遏android下载并消费掉作业,这样内部 Sc优先级调度算法rollView 就能够结束内源码编辑器编程猫下载部滑动了
class Ins源码超市ideScrollVie优先级超越50预定失利w @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : ScrollView(context, attrs, defStyleAttr) {
prigithubvate var lastX = 0f
private var lastY = 0f
override源码网 fun dispatGitchTouchEvent(motionEvent: MotionEvent): Boolean {
val x = motionEvent.x
val yandroid什么意思 = motionEvent.y
when (motionEvent.action) {
MotionEvent.ACTION_DOWN -> {
parent.requestDisallowInterceptTouchEvent(true)
}
Motion优先级行列Ev面试技巧和注意事项ent.ACTION_MOVE -> {
val deltaX = x - lastX
val deltaY = y面试毛遂自荐范文通用 - lastY
if (abs(deltaX) < abs(deltaY)) { //上下滑动的操作
if (deltaY > 0) { //向下滑动
if (scrollY == 0) { //滑动到顶部了
parent.requestDisallowIntercep优先级和劣后级的差异tTouchEvent(false)
}
} else { //向上滑动
if (height + scroll面试和面试方式Y >= comp源码编辑器编程猫下载uteVerticalScrollRange()) { //滑动到底部了
parent.优先级 劣后级requestDisal优先级排名是什么意思lowInterceptTouchEvent(false)
}
}
}
}
MotionEvent.ACTION_UP -> {
}
}
lastX = x
lastY = y
return super.dispatchTouchEvent(motionEvandroid/yunosent)
}
}
十一、面试技巧面试环节
1、作业为什么是由外向内?
在上面供应的比如里,当点击 MyTextView 区域时,最android什么意思外层的 MyRelativeLayout 仍是会最早接纳到接触作业。那么,为什么 Android 体系要将作业分发机git指令制规划成由外向内的办法呢?能不能是由内向外的办法?或许是直接只交于点击区域地址的 Vie面试毛遂自荐范文通用w 进行处理呢?
将接触作业只交于点击区域地址的 View 进行处理是必定不可的。想像个场景,一源码本钱个 ViewPager 包括了多个 Fragme源码nt,每个 Fragment 均包括一个 RecyclerView源码网,源码编辑器假定将接触作业只交于 RecyclerView 处理的话,那么 RecyclerView 能够正常照顾上下滑动的作业,可是 ViewPager 就无法左右滑动了,因为左右滑动的作业都被 RecyclerView 给消费掉了,即便该作业关于 RecyclerView 自身来说是不需求的。所以作业分发机制有必要要包括一个在父容器和子内容区域之间流通接触作业的流程,各个 View 依据各自所需来进行挑选性消费
**那能不能是由内向外的办法呢?也不合适。**一个ViewGroup 或许包括一个android11到android下载多个 View,ViewGroup 需求经过判别接触点的android/yunos坐标系坐落哪个 View 区域内来承认接触作业的下一个接纳者。而咱们知道,接触作业依照从外向内的传递次第是: DecorView -> Activity -> PhoneWindow -> Decorandroid下载View -> ContentView,因为接触作业的前期接纳者现已是处于外层的 DecorView 了,所以面试技巧依照从外向内优先级最高的运算符进行传递会愈加合适(这也仅仅我自己的个人见解,有误的话欢迎指出)
2、mFirstTouchTarget 怎样规划的?
因为接触作业的发生频率是很高的,且布局的嵌套层次也或许很深,假定每次在下发作业时都进行全量遍历的话不利于行进制造功率。为了行进作业的下发功率并削减政策的重复创立,ViewGroup 中声清楚一个 Touandroid下载chT源码本钱arget 类型的大局变量,即 mFirstTouchTandroid下载ar源码编辑器编程猫下载get
mFirstTouchTarget 中的 c优先级英文hild 变量指向消费了接触作业的轻贱 View,每个层级的 Vie面试技巧wGroup 都源码超市经过 mFirstTouchTargandroid平板电脑多少钱et 来指向轻贱,这样当优先级排序后续作业到来时,就不必通源码编辑器编程猫下载过 DFS 算法再次进行遍历了,经过 mFirsandroid手机tTouchTarget 将后续作业源码编辑器层层往下传递优先级行列给究竟的顾客
此外,TouchTarget 中优先级排序的静态成员变量 sRecycleBin 就用于供应政策复用功用,以链表的办法最多缓存 MAX_RECYCLED 个政策,调用 obtain 办法的时分就会以切换 next 引证的办法来获取一个独立的 TouchTarget 政策
private static final clas面试和面试方式s TouchTarget {
private static finaandroid下载l int MAX_RECYCLED = 32;
private static final Object sRecycleLock = new Object[0];
private static Tou源码超市chTarget sRecycleBgiticomfortin;
private static int sRecycledCount;
public static final int ALL_POINTER_IDS = -1; // all ones
// The touched child view.
@UnsupportedAppUsage
publ源码本钱ic View child;
// The combined bit mask of pointer ids for all pointers captured by tandroid平板电脑多少钱he target.
public int pointerI优先级排序dBits;
// The next target in the target list.
public TouchTarget next;
@UnsupportedAppUsage
privat源码网站e TouchTa面试常见问题及答复技巧rget() {
}
public static TouchTarget obtain(@NonNull View child, int poin面试技巧terIdBits) {
if (child == null) {
throw new IllegalArgumentException("child must be non-nandroid界面设计ull");
}
final Touchgit指令Target target;
synchronized (sRecycleLock) {
if (sRecycleBin == null) {
taandroid手机rget = new TouchTarget()优先级排名是什么意思;
} else {
target = sRecycleBin;
sRecycleBin = target.ne优先级排名是什么意思xt;
sR源码年代ecycledCou源码共享网nt面试问题--;
target.next = null;
}
}
target.child = child;
targegithubt.pointerIdBits = pointerIdBit面试和面试方式s;
return target;
}
public void recycle()优先级和劣后级的差异 {
if (child == null) {
throw优先级调度算法 new IllegalStateException("already recycled once");
}
synchronized (sRecycleL优先级排名是什么意思ock) {
if (sRecycledCount < MAX_RECYCLED) {
next = sRe面试cycleBin;
sRecycleBin = this;
sRecycledCount += 1;
} else {
next = null;
}
child = null;
}
}
}
3、讲下 ACTION_CANCEL 作业?
依照正常状况来说,每个作业序列应该是都只交由一个 View 或许 ViewGroup 进行消费的,可是还存在一种特别状况,即 View 消费了 ACTION_DOWN 作业,而后续的 ACTION_MOVgitlabE 和 A源码年代CTION_UP 作业被其上层容器 ViewGroup 阻遏了,导致 View面试必问10大问题答复 接优先级行列收不到后续作业。这会导致一些失常问题, 例如,Button 在接纳到 ACTION_DOWN 作业后 UI 后出现按压状况,假定接纳不到 ACTION_UP 这个完毕作业的话或许就无法恢复 UI 状况了。为了处理这个问giti轮胎是什么品牌题,Android 体系就经过 ACTION_CANCEL 工源码共享网作来作为工优先级排序作序列的其他一种完毕音讯
当存在上诉状况时,ViewGroup 就会经过 dispatchTransformedTouchEvent 办法结构一个 ACTION优先级排序_CANCEL 作业并将之下发给 View,然后面试使得 View 即便没有接受到 ACTION_UP 作业也能够知道本次作业序列现已完毕了
private boolean dispatchTransformedTo优先级行列uchEvent(MotionEvent event,giti boolean cancel,
View child, int desiredPointerI源码年代dBits) {
fiandroid下载软件appnal boolean handled;
// Canceling motions is a spe面试必问10大问题答复cial case. We don't need to perform any transformations
// or filtering. The important part is the action, not the contents.
final int oldAction = event.getAction();
if (cancel || oldAction == MotionEvent.面试毛遂自荐3分钟通用ACTION_CANCEL) {
event.setAction(MotionEvent.ACTION_CANCEL);
if (child == null) {
handled = super.dispatchTouchEvent(event);
} else {
handlegitlabd = child.dispatchTouchEvent(event);
}
event.setgiticomfortAction(oldAction);
return handled;
}
}
一同,ViewGroup 也会将 View 从 mFirstandroid什么意思TouchTarge面试毛遂自荐3分钟通用t 中移除,这样后续作业也就不会再检验向 View 下发了
4、onUser源码超市Inteandroid11raction 办法的效果?
前文有讲到,Activity 供应了一个空结束的 onUse面试技巧和注意事项rInteraction 办法,向子类供应了 ACTION_DOWN 作业的触发告知,那么该办法能够用优先级 劣后级来做什么呢?
onUserInteraction 办法在 Activity 接纳到 ACTION_DOWN 作业的时分才会被调用,这能够用于某些需求知道 Activity 是源码超市否处于长期“搁置”状况的需求。例优先级英文如,假定咱们需求在 Activity 没有被优先级最高的运算符操作一段时间后自动躲藏标题栏的话,就能够用该办法来设置一个定时任务控制标题栏的躲藏状况
十二、Demo 下载
上述的全优先级英文部示例代码我都放到了 Github 上,按需自取,AndroidOpenSourceDemo :https://github.com/leavesC/AndroidOpenSandroid界面设计ourceDemo