你不可以不知道的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來查找他們就是沒有問題。(這句引用自這裡/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瞭

嗯,今天就到這吧,寫這篇博客就當午休瞭娃哈哈~

 

摘自 Libaier

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *