2024年Android最新面试题八:事件分发机制(1),程序员面试

面试复习笔记:

这份资料我从春招开始,就会将各博客、论坛。网站上等优质的Android开发中高级面试题收集起来,然后全网寻找最优的解答方案。每一道面试题都是百分百的大厂面经真题+最优解答。包知识脉络 + 诸多细节。
节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

《960页Android开发笔记》

《1307页Android开发面试宝典》

包含了腾讯、百度、小米、阿里、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。熟悉本文中列出的知识点会大大增加通过前两轮技术面试的几率。

《507页Android开发相关源码解析》

只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。

真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

public class ListScrollView extends ScrollView {

private XListView xListView;

public ListScrollView(Context context) {

super(context);

}

public ListScrollView(Context context, AttributeSet attrs) {

super(context, attrs);

}

public void setxListView(XListView xListView) {

this.xListView = xListView;

}

/**

  • 覆写onInterceptTouchEvent方法,点击操作发生在ListView的区域的时候,

  • 返回false让ScrollView的onTouchEvent接收不到MotionEvent,而是把Event传到下一级的控件中

*/

@Override

public boolean onInterceptTouchEvent(MotionEvent ev) {

if (xListView != null && checkArea(xListView, ev)) {

return false;

}

return super.onInterceptTouchEvent(ev);

}

/**

  • 测试view是否在点击范围内

  • @param v

  • @return

*/

private boolean checkArea(View v, MotionEvent event){

float x = event.getRawX();

float y = event.getRawY();

int[] locate = new int[2];

v.getLocationOnScreen(locate);

int l = locate[0];

int r = l + v.getWidth();

int t = locate[1];

int b = t + v.getHeight();

if (l < x && x < r && t < y && y < b) {

return true;

}

return false;

}

}

Demo:

=====

TouchEventActivity


public class TouchEventActivity extends AppCompatActivity {

@BindView(R.id.local_btn)

LocalButton localBtn;

@BindView(R.id.local_rl)

LocalRelativeLayout localRl;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_touch_event);

ButterKnife.bind(this);

}

@Override

public boolean dispatchTouchEvent(MotionEvent ev) {

LogUtils.e(“TouchEventActivity --> dispatchTouchEvent”);

return super.dispatchTouchEvent(ev);

// return true;

}

@Override

public boolean onTouchEvent(MotionEvent event) {

LogUtils.e(“TouchEventActivity --> onTouchEvent”);

return super.onTouchEvent(event);

}

@OnClick({R.id.local_btn, R.id.local_rl})

public void onViewClicked(View view) {

switch (view.getId()) {

case R.id.local_btn:

LogUtils.e(“local_btn --> 我被点击了”);

break;

case R.id.local_rl:

break;

}

}

}

activity_touch_event


<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout

xmlns:android=“http://schemas.android.com/apk/res/android”

android:layout_width=“match_parent”

android:layout_height=“match_parent”

android:background=“@color/lightBlue”>

<com.gs.sumok2.touch.LocalRelativeLayout

android:id=“@+id/local_rl”

android:layout_width=“300dp”

android:layout_height=“300dp”

android:background=“@color/lightGreen”

android:layout_centerInParent=“true”>

<com.gs.sumok2.touch.LocalButton

android:id=“@+id/local_btn”

android:layout_width=“150dp”

android:layout_height=“150dp”

android:layout_centerInParent=“true”

android:background=“@color/lightRed”

/>

</com.gs.sumok2.touch.LocalRelativeLayout>

colors.xml


#ABDFDC

#87C09B

#B5BC85

#E7B1AD

LocalRelativeLayout


public class LocalRelativeLayout extends RelativeLayout {

public LocalRelativeLayout(Context context) {

this(context, null);

}

public LocalRelativeLayout(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

public LocalRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

}

@Override

public boolean dispatchTouchEvent(MotionEvent ev) {

LogUtils.e(“LocalRelativeLayout --> dispatchTouchEvent”);

return super.dispatchTouchEvent(ev);

}

@Override

public boolean onInterceptTouchEvent(MotionEvent ev) {

LogUtils.e(“LocalRelativeLayout --> onInterceptTouchEvent”);

return super.onInterceptTouchEvent(ev);

}

@Override

public boolean onTouchEvent(MotionEvent event) {

LogUtils.e(“LocalRelativeLayout --> onTouchEvent”);

return super.onTouchEvent(event);

}

}

LocalButton


public class LocalButton extends android.support.v7.widget.AppCompatButton {

public LocalButton(Context context) {

this(context, null);

}

public LocalButton(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

public LocalButton(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

}

@Override

public boolean dispatchTouchEvent(MotionEvent ev) {

LogUtils.e(“LocalButton --> dispatchTouchEvent”);

return super.dispatchTouchEvent(ev);

}

@Override

public boolean onTouchEvent(MotionEvent event) {

LogUtils.e(“LocalButton --> onTouchEvent”);

return super.onTouchEvent(event);

}

}

测试:

===

测试一:


Activity的dispatchTouchEvent()返回super.dispatchTouchEvent(ev),

LocalRelativeLayout的dispatchTouchEvent()返回super.dispatchTouchEvent(ev),结果如下:

TouchEventActivity --> dispatchTouchEvent

LocalRelativeLayout --> dispatchTouchEvent

LocalRelativeLayout --> onInterceptTouchEvent

LocalButton --> dispatchTouchEvent

LocalButton --> onTouchEvent

local_btn --> 我被点击了

说明: Android事件响应机制是“由外到内”分发、“由内到外”处理的形式实现的。

测试二:


将Activity的dispatchTouchEvent的返回值设为true或者false,那么事件都不会传到下一层。

  • return true : View消费所有事件。

  • return false :停止分发,交由上层控件的onTouchEvent方法进行消费,如果本层控件是Activity,那么事件将被系统消费、处理。

打印结果为:

TouchEventActivity --> dispatchTouchEvent

结论:事件被Activity拦截了。

测试三:


Activity的dispatchTouchEvent()返回super.dispatchTouchEvent(ev),

LocalRelativeLayout的dispatchTouchEvent()返回false,

  • return false :停止分发,交由上层控件的onTouchEvent方法进行消费

TouchEventActivity --> dispatchTouchEvent

LocalRelativeLayout --> dispatchTouchEvent

TouchEventActivity --> onTouchEvent

结论:LocalRelativeLayout将事件返回给Activity的onTouchEvent处理。

测试四:


Activity的dispatchTouchEvent()返回super.dispatchTouchEvent(ev),

LocalRelativeLayout的dispatchTouchEvent()返回true,

TouchEventActivity --> dispatchTouchEvent

LocalRelativeLayout --> dispatchTouchEvent

Android事件处理的三个重要函数

==================

Android事件分发机制主要由“事件分发”—>“事件拦截”—>“事件响应”这三步来进行逻辑控制的。本文也将从这三步对应的函数来分析。

2.1 事件分发:public boolean dispatchTouchEvent(MotionEvent ev)


当监听到有触发事件时,首先由Activity进行捕获,然后事件就进入事件分发的流程。Activity本身没有事件拦截,从而将事件传递给最外层的View的dispatchTouchEvent(MotionEvent ev)方法,该方法将对事件进行分发。

  • return true : View消费所有事件。

  • return false :停止分发,交由上层控件的onTouchEvent方法进行消费,如果本层控件是Activity,那么事件将被系统消费、处理。

  • super.dispatchTouchEvent(ev): 将事件交由本层的事件拦截onInterceptTouchEvent方法处理。

2.2 事件拦截:public boolean onInterceptTouchEvent(MotionEvent ev)


  • return true: 对事件拦截,交由本层的onTouchEvent进行处理。

  • return false: 不拦截,分发到子View,由子View的dispatchTouchEvent方法处理。

  • super.onInterceptTouchEvent(ev):默认表示事件拦截,交由本层的onTouchEvent进行处理。

2.3 事件响应:public boolean onTouchEvent(MotionEvent ev)


  • return true: 表示onTouchEvent处理完事件后消费了此次事件。

最后

我的面试经验分享可能不会去罗列太多的具体题目,因为我依然认为面试经验中最宝贵的不是那一个个具体的题目或者具体的答案,而是结束面试时,那一刻你的感受以及多天之后你的回味~

很多人在刚接触这个行业的时候或者是在遇到瓶颈期的时候,总会遇到一些问题,比如学了一段时间感觉没有方向感,不知道该从那里入手去学习,对此我整理了一些资料,需要的可以免费分享给大家

在这里小编分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。

【Android核心高级技术PDF文档,BAT大厂面试真题解析】

【算法合集】

【延伸Android必备知识点】

【Android部分高级架构视频学习资源】

**Android精讲视频领取学习后更加是如虎添翼!**进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

DF文档,BAT大厂面试真题解析】**

[外链图片转存中…(img-3v5fRS2i-1715683071627)]

【算法合集】

[外链图片转存中…(img-vSNSp5Ph-1715683071627)]

【延伸Android必备知识点】

[外链图片转存中…(img-J8CxJiOm-1715683071628)]

【Android部分高级架构视频学习资源】

**Android精讲视频领取学习后更加是如虎添翼!**进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值