2011-10-18 50 views
4

情境:我的佈局中有一些自定義組件。我有一個共同的佈局框架,我加載到我的Activity基類的onCreate()中,然後使用inflater將我的內容佈局加載到我的實現中,將根設置爲主佈局的內容列。findViewById(int)爲自定義視圖返回null,但不是Android內置插件

問題:當我搶的意見參考,實際提取用戶的輸入,Activity.findViewById()回報null。這可能是一個線索,我在佈局中的CheckBox和Button不會返回null;我得到了一個有關小部件的參考。

我試過的東西:我知道我正確地加載和膨脹佈局xml,因爲所有東西都顯示出來了,並且可以通過ID找到相同佈局中的標準Views。我可以與我的視圖進行交互,並將內容添加到他們和所有內容中,但我無法在我的代碼中獲得對它們的引用。

我已經嘗試清理該項目,多次。 R.id是新鮮和最新的。

我檢查了控制檯和錯誤日誌,並且沒有報告UI/XML錯誤。

我試着獲取我爲此活動加載的內容的根佈局的句柄,並調用View.findViewById()以獲取我的引用,並且返回null。如果我在調試器中檢查佈局,我可以深入查看mChildren中的視圖。

也許是另一條線索:

public VideoChooser(Context pCtxt, AttributeSet pAttrs) 
{ 
    super(pCtxt, pAttrs); 
    Log.d("VideoChooser", "Expected ID: " + R.id.vchShareVids + " | actual: " + getId()); 
} 

將導致以下的輸出:

DEBUG/VideoChooser(10372): Expected ID: 2131296271 | actual: 268435456

分配給視圖的ID不R.id的ID匹配!爲什麼會這樣?我知道它正在加載android:id屬性,否則它會是-1(View.NO_ID)。

公共佈局框架:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:foo="http://schemas.android.com/apk/res/com.foo" 
    android:id="@+id/common_frame" android:orientation="vertical" 
    android:layout_width="match_parent" android:layout_height="match_parent"> 

    <!-- top banner --> 
    <LinearLayout android:id="@+id/frame_header" android:orientation="horizontal" 
     android:layout_height="wrap_content" android:layout_width="match_parent" 
     android:layout_marginBottom="16dp"> 

     <ImageView android:src="@drawable/banner" 
      android:layout_width="wrap_content" android:layout_height="wrap_content" 
      android:layout_gravity="center_horizontal" android:layout_weight="1" /> 

    </LinearLayout> 

    <!-- content column --> 
    <LinearLayout android:id="@+id/frame_content" android:orientation="vertical" 
     android:layout_width="match_parent" android:layout_height="wrap_content" 
     android:layout_marginLeft="32dp" android:layout_marginRight="32dp" /> 

</LinearLayout> 

的內容佈局:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:foo="http://schemas.android.com/apk/res/com.foo" 
    android:id="@+id/content_panel" android:orientation="vertical" 
    android:layout_width="match_parent" android:layout_height="match_parent"> 

    <com.foo.view.VideoChooser android:id="@+id/vchShareVids" 
     foo:prompt_text="@string/prompt_share_vid" foo:prompt_size="16dp" 
     foo:preview_height="80dp" 
     android:layout_width="match_parent" android:layout_height="wrap_content" 
     android:layout_marginBottom="12dp" android:hapticFeedbackEnabled="true" /> 
    <com.foo.view.ContactChooser android:id="@+id/cchRecipients" 
     foo:prompt_text="@string/prompt_share_email" foo:prompt_size="16dp" 
     foo:preview_lines="3" foo:dialog_title="Pretend you are picking contacts" 
     android:layout_width="match_parent" android:layout_height="wrap_content" 
     android:layout_marginBottom="12dp" android:hapticFeedbackEnabled="true" /> 
    <com.foo.view.TextChooser android:id="@+id/tchDescription" 
     foo:prompt_text="@string/prompt_share_description" foo:prompt_size="16dp" 
     foo:preview_lines="1" foo:dialog_title="@string/title_msg_chooser_dlg" 
     android:layout_width="match_parent" android:layout_height="wrap_content" 
     android:layout_marginBottom="12dp" android:hapticFeedbackEnabled="true" /> 

    <CheckBox android:id="@+id/chkReshare" android:text="@string/prompt_reshare" 
     android:layout_width="wrap_content" android:layout_height="wrap_content" 
     android:checked="true" android:hapticFeedbackEnabled="true" /> 
    <Button android:id="@+id/btnSend" android:text="@string/btn_send" 
     android:layout_width="@dimen/btn_width" android:layout_height="wrap_content" 
     android:layout_gravity="center_horizontal" android:hapticFeedbackEnabled="true" /> 

</LinearLayout> 

活性基類的onCreate():

@Override 
protected void onCreate(Bundle savedInstanceState) 
{ 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.common_frame); 
} 

活動實施的onCreate():

@Override 
protected void onCreate(Bundle pState) 
{ 
    super.onCreate(pState); 
    load_content_view(R.layout.content_layout); 

    ViewGroup tLayout = (ViewGroup)findViewById(R.id.content_panel); 

    // These all return null 
    mCchVideo = (ContentChooser)tLayout.findViewById(R.id.vchShareVids); 
    mCchContact = (ContentChooser)tLayout.findViewById(R.id.cchRecipients); 
    mCchDescription = (ContentChooser)tLayout.findViewById(R.id.tchDescription); 

    // These return valid references 
    mChkReshare = (CheckBox)findViewById(R.id.chkReshare); 
    mBtnSend = (Button)findViewById(R.id.btnSend); 

    // ... 
} 

protected void load_content_view(int pResId) 
{ 
    LinearLayout tColumn = (LinearLayout)findViewById(R.id.frame_content); 
    getLayoutInflater().inflate(pResId, tColumn); 
} 
+2

提供必要的佈局XML文件和onCreate方法的代碼 – HighFlyer

+0

問題將不使用的setContentView()或者如果你創建的視圖它自身並沒有分配...更多細節展示做了一些代碼 –

+0

。讓我知道是否有任何其他代碼,你覺得是germain。 –

回答

1

是啊......我是個白癡。查看當然是設置正確的ID,然後我的一個init方法返回並對其進行了修改。

捂臉

+5

這似乎更像是一個問題評論。你的電話是否承認@HighFlyer,是的,非常感謝你關閉了這個問題。但你不是個白癡!在這裏寫一個更清楚的解釋會更好(你重寫了視圖設置的正確ID),並且忽略了自嘲和像垮掉的詞語。沒有傷害,但不要這樣下去! –

1

這是很難找到的問題沒有實際的來源。我已經根據你的帖子和完整的作品創建了示例項目。 我相信有一個非常簡單的錯誤,你會找到它。 如果你願意,你可能try it

+0

問題是,它可以工作,並且我可以獲得對Button和CheckBox等UI元素的引用。但是,儘管在佈局中顯示並且完全交互,但我的自定義小部件仍以「null」形式返回給我。這似乎是因爲他們的ID在View的構造函數中被錯誤地設置了,但我不知道怎麼可能發生。 –

12

我有一個類似的問題,併爲我的解決辦法是,以確保自定義部件的構造函數調用

super(context, attrs); 

我的構造函數沒有通過ATTRS超,因而視圖ID被搞亂了,findviewbyId返回null。

+0

優秀點! – Dr1Ku