actvity.findViewById() 与 view.findViewById()

自从学习android的hello world开始

我们就知道了这样一个函数findViewById(),他已经成为了家喻户晓,坑蒙拐骗,杀人越货必备的一个函数(好吧,这句是扯淡)

但一直用也没细致研究过它,直到写程序的时候发现一个由这个函数引起的一个莫名其妙的bug,遂决定好好研究下次函数~

我们调用的findViewById()函数其实有两种(目前我只看到两种,不确定还有没有其他的),一种是Activity类中findViewById()函数

另外一种是View类中定义的findViewById()函数

一般我们在oncreate()方法中使用的(**view)findViewById(R.id.**)既是调用的Activity中的findViewById()函数

而在其他情况写出的***view.findViewById()中调用的是view类中的findViewById()

分别看一下源代码中的实现方法及介绍

Activity类中定义的findViewById()

[java]
/**
 * Finds a view that was identified by the id attribute from the XML that
 * was processed in {@link  #onCreate}.
 *
 * @return  The view if found or null otherwise.
 */ 
public View findViewById(int id) { 
    return getWindow().findViewById(id); 

/**
 * Retrieve the current {@link  android.view.Window} for the activity.
 * This can be used to directly access parts of the Window API that
 * are not available through Activity/Screen.
 *
 * @return Window The current window, or null if the activity is not
 *         visual.
 */ 
public Window getWindow() { 
    return mWindow; 

从这里可以看出这个函数是在寻找在xml中定义的指定id的对象
View类中的findViewById()

[java]
/**
 * Look for a child view with the given id.  If this view has the given
 * id, return this view.
 *
 * @param id The id to search for.
 * @return The view that has the given id in the hierarchy or null
 */ 
public final View findViewById(int id) { 
    if (id < 0) { 
        return null; 
    } 
    return findViewTraversal(id); 
    /**
 * {@hide}
 * @param id the id of the view to be found
 * @return the view of the specified id, null if cannot be found
 */ 
protected View findViewTraversal(int id) { 
    if (id == mID) { 
        return this; 
    } 
    return null; 

从这里可以看出我们是从一个view的child view中寻找指定id的对象,所以即使几个layout的XML文件中的View的id号相同的话,只要他们没有相同的父节点,或有相同的父亲节点,但不在父节点及以上节点调用findViewById通过id来查找他们就是没有问题。(这句引用自这里http://www.2cto.com/kf/201204/127404.html
使用这个函数的常见问题:
1.既然Activity中的findViewById()是从R.java中寻找东西,那么我们就要杜绝相同名字的控件
今天自己的bug就是因为这个产生的

说到控件的命名,今天还有一个小发现

仔细看下边两段代码代码

[xml]
< ?xml version="1.0" encoding="utf-8"?> 
< LinearLayout xmlns:android="http://schemas.android.com/apk/res/android
android:id="@+id/LinearLayout" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="vertical" > 
< /LinearLayout> 
[xml]
< ?xml version="1.0" encoding="utf-8"?> 
< LinearLayout xmlns:android="http://schemas.android.com/apk/res/android
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="vertical" > 
< /LinearLayout> 
一段里边Layout没有id这个参数,一段里边有id,虽然代码不同但在outline中显示出来都是

这样在第一种情况下R.id中可以找到LinearLayout这个控件,第二种是没有的哈,这些也是以后要注意的细节

2.在调用view中的findViewById()一定要想好父View是谁!即**view.findViewById()中的**view要找对,如果没有找对父View,返回基本都是null了

时间: 2024-08-14 20:17:41

actvity.findViewById() 与 view.findViewById()的相关文章

View.findViewById()和Activity.findViewById()区别

在网上看见View.findViewById() 和 Activity.findViewById()执行效率不一样 使用Activity.findViewById()如: TextView tv_inner_1 = (TextView)this.findViewById(R.id.tv_inner_1); TextView tv_inner_2 = (TextView)this.findViewById(R.id.tv_inner_2); 使用View.findViewById() 如: Vie

Kotlin-Not enough information to infer parameter T in fun&lt;T:View&gt; findViewById(id: Int): T!

代码改变世界 错误: Type inference failed : Not enough information to infer parameter T in fun<T:View> findViewById(id: Int): T! Please specify it explicitly. 解决: holder.btnInstall = convertView.findViewById(R.id.btn_install) as Button 改为 holder.btnInstall =

android新闻端demo

学习了有一个多星期的android了,今天跟着视频来个小案例练习下,在这里记录下: 开发软件 android studio 第一步:先在activity_main.xml文件中写布局代码,这里用一个listview来展示每一条新闻 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/too

Kotlin编译时注解,简单实现ButterKnife

ButterKnife在之前的Android开发中还是比较热门的工具,帮助Android开发者减少代码编写,而且看起来更加的舒适,于是简单实现一下ButterKnife,相信把下面的代码都搞懂,看ButterKnife的难度就小很多. 今天实现的是编译时注解,其实运行时注解也一样能实现ButterKnife的效果,但是相对于编译时注解,运行时注解会更耗性能一些,主要是由于运行时注解大量使用反射. 一.创建java library(lib_annotations) 我这里创建3个annotatio

android 使用泛型再也不写findViewById方法了

我们在开发中肯定会findViewById寻找view,如果一个界面上有很多view需要绑定click事件,那么findViewById就是个体力活了,那我们就想能不能有一种办法能不能不必要每次去findViewById呢?只要你去想,说明你就意识到这个问题,剩下来就是想办法如何解决了,这个问题也不能,如果熟悉javase中的泛型,就会很简单的解决,代码入下 public <T> T $(int viewID) { return (T)findViewById(viewID); } 我们只要在

Android解决使用findViewById时需要对返回值进行类型转换问题的辅助类

在我们的开发工作时,findViewById可能是用得最多的函数之一,但它特别讨厌的地方就是我们经常需要对返回的view进行类型转换,输入麻烦.代码丑陋,例如以前我们在Activity中找一些子控件一般是这样 : @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 查

findViewById中NullPointerException的错误

最近在弄一个对话框的登录时,发现一个总是报NullPointerException的错误,折腾了两小时,一直没有发现细小的区别..先上图,一边说明原因 首先是 Activity类中定义的findViewById() * There are two methods almost all subclasses of Activity will implement: * * <ul> * <li> {@link #onCreate} is where you initialize you

告别findViewById(),ButterKnife,使用Google Data Binding Library(1)

Data Binding Library 用数据绑定编写声名性布局,可以最大限度的减少findViewById(),setOnClickListener()之类的代码.并且比起findViewById(),所有view是一次性初始化完成,性能更快. Data Binding Library具有灵活性和不错的兼容性,支持2.1以后的版本. 需要 Android Plugin for Gradle 1.5.0-alpha1或以上版本. 至于怎么升级? https://developer.androi

刚学Android遇到的问题,findViewById值为null(新版本),老鸟欢迎你的指正

环境交代: 刚学Android,在官网下载的新版的ADT 以及新版的SDK 在新版的IDE(ADT)创建项目时如果你的最小版本(minimum required SDK)要支持4.0以下版,并且目标版本为(4.0+).那么此时IDE会为你创建一个兼容包 (appcompat_v7)如下图, 创建发短信项目后就会有如下的项目目录结构 这个时候在生成的项目主Activity不是以前的那种继承的Activity,而是继承的ActionBarActivity,我把发短信的界面创建起.界面效果如下.点此时