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

Artis
  • 283
  • 2
  • 9

2 Answers2

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().

  • 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. – Artis Dec 16 '11 at 17:50
  • 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()`. –  Dec 16 '11 at 17:56
  • 3
    Note though that you can also reference the children of the ViewFlipper via [`ViewFlipper.getChildAt(index)`](http://developer.android.com/reference/android/view/ViewGroup.html#getChildAt(int)) instead of their id. E.g. like: `View first_tab = view_flipper.getChildAt(0)`. –  Dec 16 '11 at 17:59
  • Thanks, alextsc! I this has solved my problem since the count of views is fixed! – Artis Dec 16 '11 at 18:04
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.

josephus
  • 8,284
  • 1
  • 37
  • 57
  • 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. – josephus Dec 16 '11 at 18:16
  • +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. –  Dec 16 '11 at 18:26