2

关于 ScrollViews 的常见问题似乎是如何使用 fillViewport 让 ScrollView 伸展到整个屏幕。我的问题是相似的,但反过来:)

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

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

不幸的是,当将 ScrollView 包裹在 LinearLayout 周围时,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>

以下是两个版本的截图:

ScrollView 内的屏幕截图(注意滚动条和元素 1 上的裁剪) 没有 ScrollView 的截图

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

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

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

Main Activity(摘录,布局的变化是通过点击 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>
4

2 回答 2

2

正如我在评论中所说,我不知道您尝试做的事情在 xml 级别是否可行。一种选择是修改您当前的布局并添加一个根目录FrameLayout,您最初将在ScrollView其上添加LinearLayout. 在此位置,ImageView由于用户没有修改布局,因此将按照您的意愿行事。当您需要在布局中显示更多内容时,您LinearLayout将从视图层次结构中分离(with removeView)并将其附加到ScrollView(with addView)。当用户返回初始布局时,您将反转这一点。

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

于 2012-11-01T10:18:00.123 回答
0

首先,我尝试运行您的代码,但对我没有任何问题。尽管图像已缩放到我预期的 ScreenHeight-160dp 高度,但滚动视图没有显示,因为您为此图像视图使用了权重 1。

我建议您删除重量并将高度作为包装内容。在这种情况下,Imageview 将只包含图像。当它变大时,如果所有屏幕内容的总高度超过屏幕高度,则自动使用滚动视图。

于 2012-10-31T20:19:26.837 回答