Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

findViewById in a custom View to find child view

I defined a view, it extends RelativeLayout, I want to extract its children whose id are specified in layout xml file.

In 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  }  

I defined its attribute in 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>

I use this view in a layout xml file, in 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>

Here the problem comes: in HeaderView.java, line 28, 29, mHeaderContainer and mContentViewContainer are null.

It looks like that in activity_headerview.xml, the RelativeLayout whose id is headerview_header and the RelativeLayout whose id is headerview_content are not the children of HeaderView.

Did I do something wrong? Any help will be great!

like image 216
srain Avatar asked Dec 16 '13 02:12

srain


People also ask

What does findViewById return?

findViewById returns an instance of View , which is then cast to the target class. All good so far. To setup the view, findViewById constructs an AttributeSet from the parameters in the associated XML declaration which it passes to the constructor of View . We then cast the View instance to Button .

How does findViewById work on Android?

In the case of an Activity , findViewById starts the search from the content view (set with setContentView ) of the activity which is the view hierarchy inflated from the layout resource. So the View inflated from R. layout. toast is set as child of content view?

What is view in xml?

A View occupies a rectangular area on the screen and is responsible for drawing and event handling. Views are used for Drawing Shapes like Circles,Rectangles,Ovals etc . Just Use View with background and apply a Shape using Custom Drawable.


1 Answers

When your custom view constructed, the child view has not been attached to your view. try to move your code to onFinishInflate() method. this method will be invoked by the LayoutInflater after all layout has been inflated.

like image 196
Tang Ke Avatar answered Oct 17 '22 04:10

Tang Ke