自從學習android的hello world開始html
咱們就知道了這樣一個函數findViewById(),他已經成爲了家喻戶曉,坑蒙拐騙,殺人越貨必備的一個函數(好吧,這句是扯淡)java
但一直用也沒細緻研究過它,直到寫程序的時候發現一個由這個函數引發的一個莫名其妙的bug,遂決定好好研究下次函數~android
咱們調用的findViewById()函數其實有兩種(目前我只看到兩種,不肯定還有沒有其餘的),一種是Activity類中findViewById()函數ide
另一種是View類中定義的findViewById()函數函數
通常咱們在oncreate()方法中使用的(**view)findViewById(R.id.**)既是調用的Activity中的findViewById()函數學習
而在其餘狀況寫出的***view.findViewById()中調用的是view類中的findViewById()this
分別看一下源代碼中的實現方法及介紹spa
Activity類中定義的findViewById().net
[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()xml
[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了