findViewById returns null on an <include> view
Asked Answered
B

2

11

Let's get straight to code.

Activity Code, onCreate method

setContentView(R.layout.main);

View main_view = findViewById(R.id.main_view);
View view_flipper = main_view.findViewById(R.id.vf);
View first_tab = view_flipper.findViewById(R.id.prev_pane);

The main.xml layout code:

<ViewFlipper android:id="@+id/vf"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >  

    <include android:id="@+id/prev_pane" layout="@layout/vf_inner" /> 
<include android:id="@+id/cur_pane" layout="@layout/vf_inner" />
    <include android:id="@+id/next_pane" layout="@layout/vf_inner" />
</ViewFlipper>

The problem! Main view is correctly found, so is ViewFlipper, yet prev_pane or cur_pane or next_pane are not found, a null pointer is returned. Any ideas why?

This activity is called through a tab by using an Intent. All references are resolved correctly except id's on includes

When I inspect variables, I find the contents of vf_inner layout in mChildren

Beisel answered 16/12, 2011 at 17:42 Comment(0)
B
8

That's because <include /> tags are not an actual view in your UI hierachy. They are more of a copy&paste instruction for the android tools.

If you want to find the panes at runtime, add the IDs to the root elements of the included layouts. This way they can be found via findViewById().

Blond answered 16/12, 2011 at 17:47 Comment(4)
Well, all the panes are identical, yet they need to have different content. How can I achieve this? Fact is all included views contain an image and a textview with an ID. The image remains static yet the text is different for all panes.Beisel
Oh, I see. I believe XML is limited in that regard (at least I have no idea atm). You can build this from code though. Inflate three instances of the layout by using the layout inflater service, use setId() on the inflated views. Then search the ViewFlipper via findViewById() and add the three layouts via ViewFlipper.addView().Blond
Note though that you can also reference the children of the ViewFlipper via ViewFlipper.getChildAt(index) instead of their id. E.g. like: View first_tab = view_flipper.getChildAt(0).Blond
Thanks, alextsc! I this has solved my problem since the count of views is fixed!Beisel
S
0

One thing you can do is wrap the <include> statements inside a parent layout (which is still a child of your main parent layout). Give those views different ids so you can findViewById each of them separately.

Skippie answered 16/12, 2011 at 18:14 Comment(2)
They'll still be treated as children of the viewflipper, so you should have no problems with that if you just have a fixed number of views in it.Skippie
+1 Correct, I missed this possibility. That works if you need ids assigned to the children though. If you don't need these, rather use ViewFlipper.getChildAt() instead, as described in the comments of my answer. The reason for this is that you should keep the view hierachy as flat as possible. Deep nested view hierachies have a hard performance impact.Blond

© 2022 - 2024 — McMap. All rights reserved.