Alexander Dunaev
Alexander Dunaev

Reputation: 990

How to make a dynamic layout that is larger than screen?

I want to create a dynamically extending layout that may grow reflecting to user's input. First, I've created an activity layout that allows scrolling in both directions (this is not my invention, I've used the idea explained in a comment to another question with some improvements):

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:clipChildren="false"
    android:clipToPadding="false"
    tools:ignore="UselessParent" >

    <FrameLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:clipChildren="false"
        android:clipToPadding="false" >

        <RelativeLayout
            android:id="@+id/content"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:clipChildren="false"
            android:clipToPadding="false" >

        </RelativeLayout>
    </FrameLayout>
</FrameLayout>

Then, I created a simple UI layout, a text view and a vertical linear layout, below. Here is my message_with_replies.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:clipChildren="false"
    android:clipToPadding="false"
    android:orientation="vertical" >

    <LinearLayout
        android:id="@+id/header"
        android:layout_width="300dp"
        android:layout_height="wrap_content" >

<!-- some text views and buttons here, 
    I've removed them to keep things simple,
    see the screenshot below -->

    </LinearLayout>

    <LinearLayout
        android:id="@+id/replies"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:orientation="vertical" >
    </LinearLayout>

</LinearLayout>

Note the 10dp margin in the replies layout and the attributes related to clipping.

So I can now inflate an item with the message_with_replies layout and add it to the content layout of the activity, and then inflate another item and add it to the replies linear layout withing the first item and so on, thus creating a tree-like hierarchy. And the whole tree is displayed and scrolled both horizontally and vertically.

However, it looks like the layout is still limited somehow with the screen size. I have two problems:

1) The items beyond the right edge look fine but don't receive user input. 2) The layout beyond the bottom edge is messed up.

Here is the screenshot. From left to right: 1) Everything looks fine, 2) Oops, the button is on the edge, 3) Oops, the bottom is messed up.

From left to right: 1) Everything looks fine, 2) Oops the button is on the edge, 3) Oops the bottom is messed.

Looks like I missed something simple but hidden. How do I make the layout work beyond the screen edges?

Upvotes: 1

Views: 5876

Answers (1)

Alexander Dunaev
Alexander Dunaev

Reputation: 990

The solution is surprisingly simple.

In the activity layout, a RelativeLayout node (the one with content ID) should use the custom layout class that overrides the onMeasure method.

So here is the fix for the activity layout:

<com.sample.MyRelativeLayout
    android:id="@+id/content"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:clipChildren="false"
    android:clipToPadding="false" >
</com.sample.MyRelativeLayout>

and here is the class implementation:

public class MyRelativeLayout extends RelativeLayout {
    public MyRelativeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(0, 0);
    }
}

Note that I don't have to calculate anything, passing (0, 0) works just fine.

Frankly speaking, I don't yet understand all pros and cons of this solution, but it works properly. The only issue that I have noticed so far is that the more items I expand, the slower the UI responds.

I'll appreciate any comments or suggestions.

Upvotes: 10

Related Questions