3

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

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             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://schemas.android.com/apk/res/android"
    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?

Community
  • 1
  • 1
Oliver Hausler
  • 4,900
  • 4
  • 35
  • 70

1 Answers1

2

Please check if something like this fixes the issue:

fragment_board.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             android:layout_width="match_parent"
             android:layout_height="match_parent">

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

view_board.xml

 <merge xmlns:android="http://schemas.android.com/apk/res/android"

    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>

</merge>

More information on using MERGE and INCLUDE

dkarmazi
  • 3,199
  • 1
  • 13
  • 25