关于 findViewById()方法和资源 ID 的重复问题
来源:互联网 发布:团团 共青团 知乎 编辑:程序博客网 时间:2024/05/16 09:25
最近科研压力大,老板希望我把主要精力放在目前的科研课题上,对我找互联网方面工作的想法根本不屑一顾。按照他的说法,科研做得好,毕业他给推荐公司,薪资不知道比自己找工作高到哪里去了。。。虽然确实是这么回事,可是他推荐的都是电动汽车类公司,按照我现在的方向,去了肯定是做电池包热管理,虽然前途可能比较光明,可我特么想去互联网公司写代码啊!所以只能顶着压力偷偷学习了,谁让自己喜欢呢。。
今天从本地迁移一篇自己的思考笔记,可能有些同学想过这些问题但是没深究,一起来看看吧!
经过实践证明,不同的 xml 文件中,资源 ID 是可以出现重复的。且重复的 ID 在 R.java 文件中只会生成一份记录。
之所以允许出现重复,我猜想原因如下:
资源 ID 的存在是为了什么?是为了在布局中定位控件。
所以其实这个步骤是分两步走的:1.定位布局,2.定位控件。
那么只要布局的定位 ID 不出现重复,布局中控件的定位 ID 不出现重复,就是没问题的。而这也正是编码中的两个基本规范:1.xml 文件的文件名不可重复,2.xml 文件中的资源 ID 不可重复。
关于 findViewById() 方法
我们在 Activity 中常常使用的 findViewById()方法,和我们在 adapter 中常常使用的 findViewById()方法,乍一看上去,好像是同一个,其实不是同一个,但最终还真是同一个。有点绕,但看完你就明白了。
我们跟着代码先去看看Activity 中的 findViewById()方法是怎么实现的:
- 首先是 AppCompatActivity.java
@Override public View findViewById(@IdRes int id) { return getDelegate().findViewById(id); }
很明显,AppCompatAvtivity 自身没有实现这个方法,而是使用 getDelegate()返回了一个AppCompatDelegate对象,调用了AppCompatDelegate的 findViewById()方法。
跟进去发现AppCompatDelegate是个抽象类,那么这里肯定是向上转型了,AppCompatDelegate必然有一个实现类。所以我们第一反应是要看 getDelegate()方法返回的这个AppCompatDelegate对象是在哪里赋值的。
本以为会有一个 set 方法,结果发现是在 get 方法中直接就有赋值了。如下:
文件名:AppCompatActivity.java
public AppCompatDelegate getDelegate() { if (mDelegate == null) { mDelegate = AppCompatDelegate.create(this, this); } return mDelegate; }
那么我们再看看AppCompatDelegate.create(this, this);是个什么鬼就行了嘛。跟进去,发现该方法有三个重载,前两个重载的具体实现都是调用了第三个重载。第三个重载的代码如下:
文件名:AppCompatDelegate.java
private static AppCompatDelegate create(Context context, Window window, AppCompatCallback callback) { final int sdk = Build.VERSION.SDK_INT; if (BuildCompat.isAtLeastN()) { return new AppCompatDelegateImplN(context, window, callback); } else if (sdk >= 23) { return new AppCompatDelegateImplV23(context, window, callback); } else if (sdk >= 14) { return new AppCompatDelegateImplV14(context, window, callback); } else if (sdk >= 11) { return new AppCompatDelegateImplV11(context, window, callback); } else { return new AppCompatDelegateImplV9(context, window, callback); } }
果然有实现类,而且对不同的 SDK 版本其实现类还不一样。但我们跟进去会发现,上面的 lvN,lv23,lv14,lv11都是继承自 lv9,且没有重写 findViewById()方法。so,我们看看 lv9中是怎么写的吧!
如下:
文件名:AppCompatDelegateImplV9.java
@Nullable @Override public View findViewById(@IdRes int id) { ensureSubDecor(); return mWindow.findViewById(id); }
妈蛋,一层一层还真深,再看一下这个 mWindow 是什么。
如下:
文件名:Window.java
@Nullable public View findViewById(@IdRes int id) { return getDecorView().findViewById(id); }
不用说了,getDecorView()返回的肯定是一个 View 对象。所以最终还是调用了 View 的 findViewById()方法。
而在 Adapter 中,我们则是直接使用 View 的 findViewById()方法。二者也算是殊途同归了。
说到这里其实还是没说清楚资源ID 重复的情况下是如何准确找到控件的,但可以肯定的是,找控件,首先肯定得知道是在哪个 View 中找。
- 关于 findViewById()方法和资源 ID 的重复问题
- findViewById的问题和inflate(0方法
- 关于VC资源ID的一些问题
- 根据XML文件的id自动写java文件的声明方法和findViewById方法
- findViewById(R.id.listview_category)返回null的问题
- extjs中关于数据库id不能重复的问题
- 关于android之LayoutInflater的inflate()方法和findViewById()方法
- 资源ID重复错误的解决办法
- Inflater方法和findViewById()
- 关于:findViewById()返回null的问题和如何获取Fragment中的组件
- 关于:findViewById()返回null的问题和如何获取Fragment中的组件
- 关于findViewByid的简写
- 【ANDROID】Android 在oncreate() 方法中调用 findViewById 返回 null 问题的原因和解决方法
- Android中获取资源的id和url方法总结
- Activity的findViewById()和View的findViewById()
- 关于在adapter使用LinearLayout的findviewbyid问题
- MonkeyRunner之解决id重复和无id问题
- inflate和findViewById方法对比
- Idea配置远程和启动远程服务器debug
- pyhon-在原文本文件中替换某些特定的字符
- js逻辑与或非
- BZOJ 1124: [POI2008]枪战Maf 贪心 乱搞
- B
- 关于 findViewById()方法和资源 ID 的重复问题
- https://ecs-buy.aliyun.com
- NOTES of NEURAL MACHINE TRANSLATION BY JOINTLY LEARNING TO ALIGN AND TRANSLATE
- HDU1890 Robotic Sort(slpay,区间旋转)
- 0728 Java循环语句
- 大学生慕课第二周学习笔记
- uva10167--枚举
- PHP之Mysql(一)
- 设计模式讲解与代码实践(十四)——职责链