LinearLayout,包含ScrollView中子项的权重属性

时间:2012-10-31 19:19:32

标签: android layout scrollview android-linearlayout

关于ScrollViews的常见问题似乎是如何使用fillViewport让ScrollView伸展到整个屏幕。我的问题很相似,但走另一条路:)

我得到一个包含多个元素的LinearLayout。除了一个元素以外的所有元素都有一个固定的高度,特殊的一个是ImageView,它应该伸展以填充剩余的空间。这很好用:)

现在我想把LinearLayout放到ScrollView中,因为我的一些元素应该在运行时展开(例如点击“more” - 展开TextView的图标)。在未扩展版本中,我希望所有元素都适合屏幕,就好像ScrollView不存在一样。

不幸的是,当围绕LinearLayout包装ScrollView时,ImageView会缩放到maxSize,而屏幕不适合屏幕。你对如何实现我的目标有任何想法吗?

我在示例应用中重现了该问题,与您分享:

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <ImageView
            android:layout_width="fill_parent"
            android:layout_height="0px"
            android:layout_weight="1"
            android:background="#ffff0000"
            android:scaleType="fitCenter"
            android:src="@drawable/background" />

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="80dp"
        android:background="#ff00ff00"
        android:text="element 2"
        tools:context=".MainActivity" />

        <TextView
            android:layout_width="fill_parent"
            android:layout_height="80dp"
            android:background="#ff00ff00"
            android:text="element 1"
            tools:context=".MainActivity" />
    </LinearLayout>

</ScrollView>

以下是两个版本的屏幕截图:

Screenshot inside ScrollView (notice the scrollbar and cropping on element 1) Screenshot without ScrollView

上面的一个是带ScrollView的布局(注意滚动条和元素1上的裁剪),下面没有。

更新:图像视图中图像的原始高度大于屏幕。所以它应该缩小(这就是为什么它有权重1和scaleType设置)。

解决方案:以下代码为我解决了问题(基于Luksprog答案)

主要活动(摘录,通过点击ImageView引起布局的更改):

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    scrollView = (ScrollView) findViewById(R.id.scroller);
    frame = (FrameLayout) findViewById(R.id.frame);
    layout = (LinearLayout) findViewById(R.id.layout);

    final ImageView image = (ImageView) findViewById(R.id.image);
    image.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            ImageView image = (ImageView) findViewById(R.id.image);
            frame.removeView(layout);
            scrollView.addView(layout);
            image.getLayoutParams().height = image.getHeight();
        }
    });

}

布局XML文件

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/frame"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
     >

    <ScrollView 
        android:id="@+id/scroller"
        android:layout_height="fill_parent"
        android:layout_width="fill_parent"
        android:fillViewport="true"
        >

    </ScrollView>

    <LinearLayout
        android:id="@+id/layout"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <ImageView
            android:id="@+id/image"
            android:layout_width="fill_parent"
            android:layout_height="0px"
            android:layout_weight="1"
            android:background="#ffff0000"
            android:scaleType="fitCenter"
            android:src="@drawable/background" />

        <TextView
            android:id="@+id/text1"
            android:layout_width="fill_parent"
            android:layout_height="80dp"
            android:background="#ff00ff00"
            android:text="element 2"
            tools:context=".MainActivity" />

        <TextView
            android:layout_width="fill_parent"
            android:layout_height="80dp"
            android:background="#ff00ff00"
            android:text="element 1"
            tools:context=".MainActivity" />
        <TextView
            android:layout_width="fill_parent"
            android:layout_weight="0.1"
            android:layout_height="0px"
            android:background="#ff00ff00"
            android:text="element 3"
            tools:context=".MainActivity" />
    </LinearLayout>

</FrameLayout>

2 个答案:

答案 0 :(得分:2)

正如我在评论中所说,我不知道你在xml级别上是否有可能做的事情。一种选择是修改当前布局并添加一个根FrameLayout,您最初将添加ScrollView及其上方LinearLayout。在此位置,ImageView将按照您的需要运行,因为用户未修改布局。当您需要在布局中显示更多内容时,您将从视图层次结构(LinearLayout)中分离removeView并将其附加到ScrollView(带addView)。当用户返回初始布局时,您将撤消此操作。

这会使ImageView在进行视图切换时具有不同的高度,因此您需要获得ImageView的高度并在进行切换时重新设置它。要获得高度,您可以在侦听器中或使用post中的onCreate方法执行此操作(因为此时尚未显示视图)。此外,请记住,用户可以打开手机,我不知道这是否会影响您的布局,但需要考虑。

答案 1 :(得分:0)

首先,我尝试运行您的代码,但这对我没有任何问题。 scrollView没有显示,虽然图像被缩放到ScreenHeight-160dp高度,这是我预期的,因为你已经使用了权重1来进行这个imageview。

我建议你去除重量并给出高度作为包裹物。在这种情况下,Imageview将只包含图像。当它变得更大时,如果所有屏幕内容的总高度超过屏幕高度,则自动滚动视图开始使用。