tags:

views:

177

answers:

2

In my foo_layout.xml file I have a subclassed RelativeLayout:


<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <com.android.myapp.FooView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="@drawable/pegboard_table"
        android:orientation="vertical"
        android:scaleType="fitXY"
        >
        <ImageView   
        android:id="@+id/triangular"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:src="@drawable/pegboard_board"
        android:scaleType="fitXY"
    android:gravity="center"
        android:visibility="invisible"
        />
        <Chronometer
        android:id="@+id/timer"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/timer_display"
        android:textSize="40sp"
        android:textColor="#000"
        android:layout_alignParentTop="true"
        android:gravity="center"
        android:visibility="invisible"/>
         <TableLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/board_table"
        android:visibility="invisible"
        />
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:gravity="center_horizontal"
        android:background="@drawable/tab_bar">
        <!-- android:layout_alignLeft="@id/options_tab"-->
        <ImageView 
        android:id="@+id/game_select"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:src="@drawable/game_select" android:paddingLeft="15sp"/>
        <ImageView 
        android:id="@+id/undo_select"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/game_select"
        android:layout_weight="1"
        android:src="@drawable/undo"
        />
        <ImageView 
        android:id="@+id/settings_select"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/undo_select"
        android:layout_weight="1"
        android:src="@drawable/settings"
        />   
        <ImageView 
        android:id="@+id/info_select"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/settings_select"
        android:layout_weight="1"
        android:src="@drawable/info"
        />
    </LinearLayout>
        </com.android.myapp.FooView>
</FrameLayout>

Then I have a java file FooView.java with the class extending RelativeLayout.


package com.android.myapp;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TableLayout;

public class FooView extends RelativeLayout {

    public FooView(Context context) {
        super(context);
        fillTable();
        // TODO Auto-generated constructor stub
    }

    public FooView(Context context, AttributeSet attrs) {
        super(context, attrs);
        fillTable();
        // TODO Auto-generated constructor stub
    }

    public FooView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        fillTable();
        // TODO Auto-generated constructor stub
    }

    public void fillTable() {
        int board = this.getChildCount();
                View boardView = findViewById(R.id.board_table);
        if (board > 0)
            ;
    }

}

board is always 0. boardView is always null.

This doesn't seem like the right behavior. I've tried it with other views inside the FooView hierarchy and findViewById() always returns null.

For the life of me I can't figure out what I'm doing wrong.

A: 

The image view and chronometer view are not part of the custom view until you add them using view.setlayout in the constructor.

Hans
A: 

First, your widget is attempting to reference widgets outside of itself. Calling findViewById() will get you children of your widget, not widgets elsewhere in the layout.

Second, you are trying to do this from your constructor. That is not safe. Please wait until onFinishInflate().

Third, you may not want to hardwire in R.id values for those other widgets, but allow those to be configurable, either through view attributes or setters. To access those widgets, given the configured IDs, you would call findViewById() not on yourself, but on your activity, obtained from getContext().

CommonsWare
Thanks for your answer. Makes sense. I had assumed widgets inside my sub-classed widget in the XML were automatically children of my widget. This is not the case?
Joel Cron
Sorry, I missed a tag. Yes, they will be your children, but not until `onFinishInflate()`. They haven't even been created yet when your constructor gets called.
CommonsWare