findViewById在自定义视图中查找子视图

sra*_*ain 10 android android-custom-view findviewbyid

我定义了一个视图,它扩展了RelativeLayout,我想提取其id在layout xml文件中指定的子节点.

HeaderView.java:

  1  package com.example.test; 
  2   
  3  public class HeaderView extends RelativeLayout { 
  4                         
  5      public HeaderView(Context context, AttributeSet attrs) {  
  6          this(context, attrs, 0);        
  7   
  8          TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.HeaderView, 0, 0);  
  9   
 10          int headerId = 0; 
 11          int containerId = 0;            
 12                         
 13          //  find attributes
 14          if (arr != null) { 
 15              if (arr.hasValue(R.styleable.HeaderView_headerview_header)) { 
 16                  headerId = arr.getResourceId(R.styleable.HeaderView_headerview_header, 0); 
 17              }  
 18              if (arr.hasValue(R.styleable.HeaderView_headerview_container)) { 
 19                  containerId = arr.getResourceId(R.styleable.HeaderView_headerview_container, 0); 
 20              }  
 21              arr.recycle(); 
 22          }  
 23   
 24          Log.d("test", String.format("headerId: %s, containerId %s", headerId, containerId)); 
 25          // headerId: 2131296260, containerId 2131296259 
 26           
 27          // here: mHeaderContainer is null  
 28          mHeaderContainer = (RelativeLayout) findViewById(headerId); 
 29          mContentViewContainer = (RelativeLayout) findViewById(containerId); 
 30      }  
 31  }  
Run Code Online (Sandbox Code Playgroud)

我在其中定义了它的属性headview_attrs.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="HeaderView">
        <attr name="headerview_header" format="reference" />
        <attr name="headerview_container" format="reference" />
    </declare-styleable>

</resources>
Run Code Online (Sandbox Code Playgroud)

我在布局xml文件中使用此视图,位于activity_headerview.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:test="http://schemas.android.com/apk/res/com.example.test"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.example.test.HeaderView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        test:headerview_container="@+id/headerview_content"
        test:headerview_header="@+id/headerview_header" >

        <RelativeLayout
            android:id="@+id/headerview_header"
            android:layout_width="match_parent"
            android:layout_height="30dp" >
        </RelativeLayout>

        <RelativeLayout
            android:id="@+id/headerview_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >
        </RelativeLayout>
    </com.example.test.HeaderView>

</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)

这里出现问题:in HeaderView.java, line 28, 29, mHeaderContainermContentViewContainernull.

它看起来像在activity_headerview.xml中,RelativeLayoutid为headerview_headerRelativeLayoutid为headerview_content不属于孩子们 HeaderView.

我做错什么了吗?任何帮助都会很棒!

Tan*_* Ke 17

构建自定义视图时,子视图尚未附加到视图中.尝试将您的代码移动到onFinishInflate()方法.在所有布局都被夸大后,LayoutInflater将调用此方法.