dimanche 17 mai 2015

StackOverflowError when inflating custom view which contains its own views

I am having a Fragment, where I inflate "fragment_board.xml":

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://ift.tt/nIICcg"
             android:layout_width="match_parent"
             android:layout_height="match_parent">

    <view
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="com.app.BoardView"
        android:id="@+id/view_board"/>
</FrameLayout>

As you can see, fragment_board contains a custom view "BoardView", from where I want to load the following "view_board.xml":

<com.app.BoardView xmlns:android="http://ift.tt/nIICcg"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbars="none"
    android:fadingEdge="none"
    android:requiresFadingEdge="none"
    android:overScrollMode="always"
    android:id="@+id/board_scrollview_vertical">

    <android.widget.HorizontalScrollView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:scrollbars="none"
        android:fadingEdge="none"
        android:requiresFadingEdge="none"
        android:overScrollMode="always"
        android:id="@+id/board_scrollview_horizontal"
        android:foregroundGravity="left">

    </android.widget.HorizontalScrollView>

</com.app.BoardView>

My custom view contains two scroll views (I use it for panning), and I want to be able to re-use it in other layouts. The BoardView extends the outer (vertical) scroll view like this:

public class BoardView extends ScrollView

When I use it stand-alone, it inflates fine and I can findViewById() both scroll views in the inflated layout. But when I use it in a layout tree (such as a fragment), I run into problems.

In the fragment, I inflate the layout tree like this:

View view = inflater.inflate(R.layout.fragment_board, container, false)

From the fragment, I can findViewById() the outer (vertical) scroll view, but findViewById() returns null for the inner (horizontal) scroll view.

In BoardView, I inflate like this:

View view = inflate(getContext(), R.layout.view_board, this);

As said, I can find both scroll views fine when inflated by itself, but when inflated as part of the fragment, I get StackOverflowError.

It is clear why: I inflate in the fragment first, and then I inflate the same XML in the view again, which triggers another inflation of the view and so on. I get a cyclic reference here. Problem I can't figure out how I can add the inner (horizontal) scroll view to the already existing layout. I think I need to merge somehow or inflate layouts manually, but I can't figure out how.

Here are some refs (which didn't help in my case):

Can anybody suggest what I should do. If possible, I'd want BoardView to work as a generic component, which I can plug into a layout tree where needed.

As Android [according to one of the refs above] does not officially support composite components, would my best option be to drop XML layouts for the inner views and add them in code?

Aucun commentaire:

Enregistrer un commentaire