findViewById方法探究

Android findViewById及替代方案大全 自打学习Android开发以来,findViewById就是我使用最频繁的函数之一。findViewById可为灵活至极,但是又让人爱恨交加。那findViewById究竟有哪些优缺点,他又有哪些替代方案呢?今天就来做一个总结 findViewById findViewById的原理 findViewById的原理非常简单,我们都知道Android中的View结构是一个树形结构,findViewById就是自树的根节点,依次遍历其子节点,知道找到目标的id。 findViewById的优点 还是先夸夸fi 阅读详情

        配置布局的xml文件时,有时会给View配置id,而在Activity中寻找到该View的方法就是通过该id号来找到该View的。具体调用的方法就是findViewById。

        这个findViewById方法顾名思义,就是根据id来找到View,而Android内部的实现,也同样遵循了这个原则。具体见下面的源代码分析。

        Activity中的findViewById方法执行流程如下:Activity.findViewById() >> Window.findViewById() >> DecorView.findViewById()。在这个流程中,没有干具体的事情,只是一步步调用到了DecorView的findViewById方法。


Activity.java

// findViewById方法
public View findViewById(@IdRes int id) {
    return getWindow().findViewById(id);
}
 
// getWindow方法,获取到activity对应的window对象
public Window getWindow() {
    return mWindow;
}

PhoneWindow.java

public View findViewById(@IdRes int id) {
    return getDecorView().findViewById(id);
}
 
// 获取到root View,而该root View继承自FrameLayout
public final View getDecorView() {
    if (mDecor == null) {
        installDecor();
    }
    return mDecor;
}

        DecorView继承自FrameLayout,是根View,可以理解为整个View树的起始点,联想测量、布局、绘制以及事件分发消费,那么findViewById也是这样的处理思路,概括来说,Activity的findViewById方法就是从根View自身开始,遍历自身子View,尝试查找View树中是否存在mID等于id的View或ViewGroup。说是尝试,因为也有可能找不到。

        从Root View开始,就是要正式进入到寻找mID为id的View或ViewGroup过程了。具体执行流程参考如下:View.findViewById() >> ViewGroup.findViewTraversal() >> View.findViewById() >> ViewGroup.findViewTraversal() >> View.findViewById() >> View.findViewTraversal()。


View.java

// 根据给定的id找指定的View(ViewGroup不能重写)
public final View findViewById(@IdRes int id) {
    if (id < 0) { // id不能为负数
        return null;
    }
    // 调用findViewTraversal方法
    return findViewTraversal(id);
}
 
// 通过遍历找到View
protected View findViewTraversal(@IdRes int id) {
    if (id == mID) {
        // 如果id号与View的mID一致,则返回View自身
        return this;
    }
    // 否则返回null
    return null;
}


ViewGroup.java

// 重写了View的findViewTraversal方法,通过遍历找到View
protected View findViewTraversal(@IdRes int id) {
    // 如果id号恰好与viewgroup的mID一致,就返回ViewGroup自身
    if (id == mID) {
        return this;
    }
 
    final View[] where = mChildren;
    final int len = mChildrenCount;
 
    // 遍历子View,
    for (int i = 0; i < len; i++) {
        View v = where[i];
 
        if ((v.mPrivateFlags & PFLAG_IS_ROOT_NAMESPACE) == 0) {
            // ①如果该子View是ViewGroup,就继续先判断自身的mID是否匹配
            //   如果不匹配,再遍历该ViewGroup的子View,继续判断是否匹配,依次循环下去
            // ②如果该子View是View,就直接判断View的mID是否匹配
            v = v.findViewById(id);
 
            if (v != null) {
                // 如果匹配成功,则返回找到的这个View对象
                return v;
            }
        }
    }
    // 所有子View及其ViewGroup自身的mID都不能匹配上id号,那么就找不到该id号匹配的View了,返回null
    return null;
}

        由于View的findViewById是final,所以ViewGroup不可以重写。而我们可以注意到在View的findViewById中对id是否为负数进行了判断,那么问题来了,为什么不在Activity中判断呢?每次都判断不是浪费时间吗?
        因为不仅Activity会调用findViewById方法,当用LayoutInflater导入一个自定义的布局时,也有需要根据布局中定义的id来找到对应的View,从而进行处理。此时,也要进行判断id是否为负数。


        总结如下,Activity的findViewById最终还是会调用到View的findViewById方法;Activity的findViewById方法就是从根View自身开始,遍历自身子View,尝试查找View树中是否存在mID等于id的View或ViewGroup;View的findViewById方法就是从该View自身开始,遍历自身子View,尝试查找该View的树中是否存在mID等于id的View或ViewGroup。





Adapter简化写法以及findViewById()方法的优化 首先写个ViewHolder: public class ViewHolder { private View mConvertView; private Activity mActivity; private SparseArray mViewArray; // 包含了View引用的SparseArray public ViewHolder(View 阅读详情

相关推荐

PAM4信号测试实战:从眼图分析到误码率测量的技术演进

在高速数字系统设计中,信号完整性测试是确保数据传输可靠性的核心环节。其基本原理在于通过时域和频域分析,精确评估信号在传输过程中的质量衰减与失真。随着数据速率向56Gbps及以上演进,传统的NRZ编码面临带宽瓶颈,而PAM4调制技术通过在每个符号周期内承载更多比特信息,成为提升信道效率的关键路径。这项技术的工程价值在于,它允许在相同带宽下实现翻倍的数据吞吐量,这对于数据中心互联、PCIe 6.0及800G以太网等高速接口至关重要。然而,PAM4信号电平间距更小,对噪声和抖动极为敏感,导致其原始误码率显著升高,

weixin_42522817的博客 655

[android]深入理解findViewById原理

用的太多了,但是不知道原理。Xutils里面舍弃了findViewById改用注解,当时也很不理解。一步步了解后,发现,相比注解的方式加载控件,findViewById的效率是很低的。 点进去看源码进入Activity.class类里的方法: 发现这个返回的是getWindow()的findViewById方法,这个getWindow()是什么? Activity.class

努力奋斗 2万+

边云协同智能进化:大模型与小模型的动态训练与高效部署策略

本文深入探讨了边云协同架构下大模型与小模型的动态训练与高效部署策略。通过物流分拣、医疗影像等实战案例,展示了如何利用边云协作框架实现AI模型的智能进化,显著提升处理效率与准确性。重点解析了动态任务分配、增量学习和知识蒸馏等关键技术,为分布式训练场景提供优化方案。

work3的博客 190

findViewById原理

findViewById原理 前言 从表面上来看,findViewById就是根据R文件中的id值查询到相应的View,然后返回。  那么问题来了,这些View是在find的时候才被实例化还是父View实例化好的时候就已经实例化好了,findViewById只是从数据源中取出来。  答案是在父类被实例化好的时候就已经完成了子类的实例化,并且形成了一个DOM树。这个DOM数其

zjy519893509的专栏 1万+

OPTI Toolbox v2.28 安装与 3 个求解器补全:SCIP、SeDuMi、MOSEK 配置详解

本文详细介绍了OPTI Toolbox v2.28在MATLAB环境下的完整安装指南,包括SCIP、SeDuMi和MOSEK三个关键求解器的配置与优化技巧。通过分步指导和实战案例,帮助用户高效搭建强大的优化工具包,提升混合整数规划、二次约束二次规划等复杂问题的求解效率。

weixin_29039773的博客 350

Linux文件操作四剑客

① /^(d{2}|d{4})-((0([1-9]{1}))|(1[1|2]))-(([0-2]([1-9]{1}))|(3[0|1]))$/ // 年-月-日 yyyy-MM-dd / yy-MM-dd 格式。⑥“^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$” //正浮点数。

wuds_158的博客 1609

讲解findViewById的用法&是做什么的

安卓编程的定位函数,主要是引用.R文件里的引用名。一般在R.java文件里系统会自动帮你给出你在XML里定义的ID或者Layout里面的名称,例如:Button button=(Button)findViewById(R.id.button01);这样就引用了XML(res里的布局文件)文件里面的button,使得在写.java的按钮时能与XML里的一致。

ProveYourself的博客 4万+

restbed编译笔记

Restbed 可以构建出基于asio库的restfulAPI服务,Restbed 4.7版本使用了1.12.0版本的asio(其他版本编译不通过),可直接访问github下载:https://github.com/chriskohlhoff/asio/tree/asio-1-12-0。另外Restbed还依赖openssl库(可直接下载exe的安装包,安装后取出lib库及头文件放到到restbed\dependency\openssl中即可,https://slproweb.com/download/W.

mahong100的博客 2106

安卓findViewById 的优化方案:ViewBinding与ButterKnife(一)

安卓findViewById 的优化方案:ViewBinding与ButterKnife(一)

u013083465的专栏 1929

21、二维卷积层(convolution2dLayer)的全面解析

本文全面解析了二维卷积层(convolution2dLayer)的原理、属性和应用,详细介绍了其在深度学习中的作用及实现方法。文章涵盖创建卷积层的语法、参数设置、算法原理、输入输出格式、优化策略以及实际应用案例,旨在帮助读者更好地理解和应用二维卷积层构建高效的深度学习模型。

red88的博客 312

halcon知识:常见三种模板匹配方法总结

halcon的三种模板匹配方法总结,halcon有三种模板匹配方法:即Component-Based、Gray-Value-Based、Shaped_based,分别是基于组件(或成分、元素)的匹配,基于灰度值的匹配和基于形状的匹配,此外还有变形匹配和三维模型匹配也是分属于前面的大类 本文只对形状匹配做简要说明和补充: Shape_Based匹配方法: 上图介绍的是形状匹配做法的一般流程及模板制作的两种方法。 先要补充点知识:形状匹配常见的有四种情况 一般形状匹配模板shape_model、线性变

gongdiwudu的专栏 4万+

通过对inflate与 findViewById 方法的探究深度了解一下Android

目前为止,很多大牛已经纷纷发表了对inflater.inflate方法与findViewById方法的见解。从概要上,小编总结了一下讲得比较靠谱的说法,之后会针对这方面进一步做一下测试探究,帮助Android新手更进一步了解一下我们正在一个什么样的平台上怎样便利地开发着一款软件。 ==========================================================

小轩腾空的专栏 895

基于STM32单片机设计的红外人脸测温仪(QT上位机)

基于STM32单片机设计的红外人脸测温仪(QT上位机)是一种结合红外测温和人脸识别技术的设备,可以快速、非接触地测量人体体温并识别身份,广泛应用于人员密集场所的体温筛查和出入管理。基于STM32单片机设计的红外人脸测温仪是一种功能实用、易于使用的人脸测温设备,可以有效提高测温效率和识别准确率,广泛应用于各类人员密集场所的体温筛查和出入管理。

走向CTO的路上... 1719

android--android studio findViewById 出现 Ambiguous method call. Both

上面这张图是盗的图,因为我的问题已经解决了,,没截图。 问题: 如图所示,findViewById()方法在Activity中和AppCompatActivity中都存在,所以编译器不知道你用的哪一个。 解决: 我参考了若干篇抄来抄去的博客文章,最后没找到解决办法。最后将API升级到26,错误就消失了。 原理: 我也不知道。 > 哪位大佬知道这是怎么回事,万望在评论区告诉在下,再次先行谢过...

ihan.的博客 942

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

VB摄像头监控

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

Android中通过注解代替findViewById方法

这篇文章主要讲解注解实现findViewById的功能,首先我们来熟悉一下在java中怎么定义一个注解和解析一个注解 注解的概念是在jdk5.0中提出来的,在java.lang的包中已经定义了三个注解:Override,Deprecated,SuppressWarnings Override相信大家非常熟悉,就是表明这个方法是改写了父类的方法 Deprecated表示在新版本的 jdk中已经

Android学习之旅 5636

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

inflate 方法与 findViewById方法的区别

不同点:layoutinflater是用来找res/layout/下的xml布局文件,并且实例化;而findviewbyid()是找xml布局文件下的具体widget控件(如button、textview等)。 具体作用: 1、对于一个没有被载入或者想要动态载入的界面,都需要使用layoutinflater.inflate()来载入; 2、对于一个已经载入的界面,就可以使用act

amao的博客 542

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

关于在findViewById()方法时遇到的一些问题

最近需要做一个关于色卡的App,需要用到LayoutInflater来实现标签动态切换View界面,但是发现在使用过程中App突然会闪退, 闪退目前已解决。 先看下关于findViewById()的详细介绍:findViewById()是找具体某一个xml下的具体 widget控件(如:Button,TextView等) 我的闪退原因:我将findViewById()用在了还没有动态加载我要查找...

Jason的学习笔记 1287

关于Android 开发中 Java方法findViewById的使用

在实际开发中,当遇到有很多UI组件时,各个组件会通过andriod:id 属性给每个组件设置一个唯一的标识。当需要在代码中访问指定的组件时(例如设置单击事件),就可以通过id值,利用方法findViewById(R.id.id值)来访问。 例如: public class MainActivity extends AppCompatActivity { Button bn ; EditText s...

hdfinder的博客 1万+

kotlin代替findViewById的方法

在安卓项目使用了Kotlin之后,发现Kotlin一个相当强大的地方,可以不用findViewById,引入布局,直接使用控件 方式一:使用kotlin插件自动生成 引入kotlin扩展插件 apply plugin: ‘kotlin-android-extensions’ 引入kotlin自动生成的相关布局文件 import kotlinx.android.synthetic...

king的专栏 6696

Fragment中使用findViewById

如果你为Fragment在XML文件中创建了什么控件,但findViewById方法却只能被用在Activity类中,所以,有没有办法在Fragment中使用它呢 使用getView()方法就OK了,因为这个方法最终会返回当前fragment的根视图。 Button btn = (Button) getView().findViewById(R.id.btn); 但是在此之前要使用onCreateView来创建视图。 @Override public View onCreateView(L

半甜去冰的博客 2386

findViewById返回空指针的解决方法

用Toast来输出一SQL语句,结果当我调用TextView tv = (TextView) findViewById(R.id.toast_tv);时, 总是返回空指针。 找了例子程序, 通过仔细比对, 发现正确的语句应该是TextView tv = (TextView) view.findViewById(R.id.toast_tv);   此处的view是通过一个LayoutInf

cc_lq的专栏 1811

Android开发中简化findViewById的几种方法

这几天查资料,DataBind暂且不谈,简化findViewById方法主要有三种:1、注解;2、另类写法;3、已有框架。 1、注解,这是通过反射的原理,自已写注解方法,可以参考该网址:http://www.cnblogs.com/Fndroid/p/5354644.html。 2、另类写法,使用泛型可以简化强制转化的步骤,该方法在BaseActivity中使用findViewById,参考网

木偶16的博客 2417

findViewById 原理

有人问了 findViewById 到底做了什么事情,有点懵逼,在此深入研究以下 findViewById 流程图 1. Activity 的 findViewById 点进去看源码进入 Activity.class 类里的方法: /** * Finds a view that was identified by the id attribute from the XML t...

怪咖先森的博客 2297

dialog也有findViewById方法

dialog也有findViewById方法,由此可以通过这个方法,来通过Id获得包含在这个Dialog的layout文件中的控件。

2969

Android-findViewById()方法分析

findViewById()方法分析首先,看我们在Activity中调用的findViewById方法:@Nullable public View findViewById(@IdRes int id) { return getWindow().findViewById(); }调用了Window的findViewById()方法,获取结果。那么下面,我们就来看看Window

Abe的学习之路 7519

inflate和findViewById方法对比

Inflate()作用就是将xml定义的一个布局找出来,但仅仅是找出来而且隐藏的,没有找到的同时并显示功能。最近做的一个项目就是这一点让我迷茫了好几天。 android上还有一个与Inflate()类似功能的方法叫findViewById(),二者有时均可使用,但也有区别 区别在于: 如果你的Activity里用到别的layout,比如对话框layout,你还要设置这个lay

白马笑西风的专栏 1327
上一篇: Android自定义View训练【2】
下一篇: Activity中使用Dialog的方式
Sun_Jingjing
博客等级 码龄10年 1粉丝 23原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值