The Situation: I have some custom components in my layout. I have a common layout frame that I load in my Activity base class's onCreate()
, and then load my content layouts in my implementations using an inflater, setting the root to the content column of the main layout.
The Problem: When I grab a reference to the Views, to actually extract the user's input, Activity.findViewById()
returns null
. It is perhaps a clue that the CheckBox and Button I have in the layout do NOT return null
; I get a valid reference to the widget.
Things I've Tried: I know I am properly loading and inflating the layout xml, because everything shows up, and the standard Views in the same layout can be found by ID. I can interact with my Views and put content into them and everything, but I can't get a reference to them in my code.
I have tried cleaning the project, multiple times. R.id
is fresh and up-to-date.
I have checked the Console and Error Log, and there's no UI/XML errors reported.
I tried getting a handle to the root layout of the content I loaded for this activity, and calling View.findViewById()
to get my references, and that returns null
, too. If I examine the layout in the debugger, I can drill down and find my Views in mChildren
.
Perhaps another clue:
public VideoChooser(Context pCtxt, AttributeSet pAttrs)
{
super(pCtxt, pAttrs);
Log.d("VideoChooser", "Expected ID: " + R.id.vchShareVids + " | actual: " + getId());
}
will result in the following output:
DEBUG/VideoChooser(10372): Expected ID: 2131296271 | actual: 268435456
The ID assigned to the View doesn't match the ID in R.id
! Why would that be? I know it's loading the android:id
attribute, or else it would be -1 (View.NO_ID
).
The Common Layout Frame:
<?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>
The Content Layout:
<?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>
Activity Base Class onCreate():
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.common_frame);
}
Activity Implementation 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);
}
I had a similar problem and the solution for mine was to make sure the constructor of the custom widget calls
super(context, attrs);
My constructor didn't pass attrs to super and thus the view id was messed up and the findviewbyId returned null.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With