ScrollView溢出其FrameLayout父级 [英] ScrollView overflowing its FrameLayout parent

查看:117
本文介绍了ScrollView溢出其FrameLayout父级的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个复杂的LinearLayout(垂直),其中FrameLayout在其他内容上方(TextViewEditText框). FrameLayout包含两件事:a)地图和b)包含半透明的LinearLayoutScrollView,该半透明的LinearLayout覆盖"地图. ScrollView最初是GONE,但我以编程方式使其可见.我还以编程方式将视图添加到嵌入在ScrollView中的LinearLayout中.

I have a complicated LinearLayout (vertical) with a FrameLayout above some other stuff (a TextView and an EditText box). The FrameLayout contains two things: a) a map and b) a ScrollView containing a semi-transparent LinearLayout that 'overlays' the map. The ScrollView is initially GONE, but I render it visible programmatically. I also programmatically add Views into the LinearLayout embedded in the ScrollView.

使用onMeasure()设置FrameLayout的尺寸,以使高度和宽度相等.这使得FrameLayout占据了设备屏幕的顶部,而TextViewEditText则位于下面.

The FrameLayout dimensions are set using onMeasure() so that the height and width are equal. This make the FrameLayout take up the top portion of the device screen while the TextView and EditText fit below.

public static class MyFrameLayout extends FrameLayout {

    public FrameLayoutWithMap(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public void onMeasure(int widthSpec, int heightSpec) {
        super.onMeasure(widthSpec, heightSpec);
        int size = Math.min(getMeasuredWidth(), getMeasuredHeight());
        setMeasuredDimension(size, size);
    }
}

一切从一开始就很有效.但是,当我向嵌入在ScrollView中的LinearLayout中添加足够的视图时,ScrollView最终将在FrameLayout下面的TextView后面处扩展.换句话说,ScrollView溢出其FrameLayout父级,然后将其底部隐藏.当我继续将视图添加到ScrollView中嵌入的LinearLayout中时,ScrollView最终将开始滚动.一旦ScrollView是设备屏幕的高度,就好像发生了这种情况.

Everything actually works great in the beginning. However, when I add enough Views to the LinearLayout embedded in the ScrollView the ScrollView will eventually extend behind the TextView below the FrameLayout. In other words, the ScrollView overflows its FrameLayout parent, the bottom of which is then hidden. As I continue to add Views to the LinearLayout embedded in the ScrollView the ScrollView will eventually start scrolling. It appears as though this happens once the ScrollView is the height of the device screen.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activityRoot"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#323232"
    tools:context=".MainActivity" >

    <FrameLayout
        class="com.myapp.main.MyFrameLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#070707" >

        <com.myapp.main.MapView
            android:id="@+id/map"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <ScrollView
            android:id="@+id/overlayScrollView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:layout_gravity="left"
            android:scrollbars="vertical"
            android:fillViewport="false"
            android:visibility="gone" >
            <LinearLayout
                android:id="@+id/overlayLinearLayout"
                android:orientation="vertical"
                android:layout_width="100dp"
                android:layout_height="wrap_content"                
                android:padding="1dp"       
                android:background="#AA000000" >
            </LinearLayout>
        </ScrollView>

    </FrameLayout>

    <TextView
        android:id="@+id/tvMessage"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="left"
        android:textColor="#FFFFFF"
        android:textSize="14sp" />

    <EditText android:id="@+id/entry"
        android:background="@drawable/entry_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:lines="1"
        android:singleLine="true"
        android:textSize="16sp"
        android:textColor="#ffffff"
        android:hint="@string/entry" />

</LinearLayout>

我想让ScrollView在其FrameLayout父级的高度后开始滚动.换句话说,我希望ScrollView保留在其FrameLayout父级中包含.

What I would like to happen is for the ScrollView to start scrolling as soon as it's the height of its FrameLayout parent. Put another way, I'd like for the ScrollView to remain contained within its FrameLayout parent.

你知道我在做什么错吗?

Any idea what I'm doing wrong here?

推荐答案

更新:

新的 ConstraintLayout 库为您提供了细粒度控制您的视图相对于父视图和其他视图的大小.它还支持长宽比,因此您可以(例如)强制视图始终为正方形.

The new ConstraintLayout library gives you fine-grained control of how your views are sized in relation to the parent and to other views. It also supports aspect ratios, so you can (for instance) force a view to always be square.

原始回复:

问题在于您如何测量特殊的FrameLayout.当您调用super.onMeasure()时,此视图及其所有子视图将根据给定的度量规范对其进行度量.在那之后,您限制了该视图的尺寸,但是它的所有子视图都没有意识到.只有该视图及其 parent 知道这一点.它的孩子已经测量出自己的想法,认为此视图的大小不受您对setMeasuredDimension()的额外调用所限制.

The problem is how you are measuring your special FrameLayout. When you call super.onMeasure(), this view and all of its children will measure themselves according to the measure specs given. After that, you constrain the dimensions of this view, but none of its children are aware of this; only this view and its parent are aware of this. Its children have measured themselves thinking the size of this view is not constrained by your extra call to setMeasuredDimension().

再次调用super.onMeasure()将迫使其子级重新测量自己,从而通知他们新的尺寸.

Calling super.onMeasure() again will force its children to measure themselves again, thereby informing them of the new size.

@Override
public void onMeasure(int widthSpec, int heightSpec) {
    super.onMeasure(widthSpec, heightSpec);
    int size = Math.min(getMeasuredWidth(), getMeasuredHeight());
    int spec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
    super.onMeasure(spec, spec);
}

请注意,这将导致此视图及其所有子级在每次测量通过时都进行两倍的测量,因此它可能不是性能最高的方法,但是它将完成您想要的操作.

Note this will cause this view and all its children to measure twice as many times with each measure pass, so it might not be the most performant approach, but it will accomplish what you want.

这篇关于ScrollView溢出其FrameLayout父级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆