【问题标题】:android ScrollView layout (wrap_content, maximum size)android ScrollView 布局(wrap_content,最大尺寸)
【发布时间】:2012-03-16 11:08:17
【问题描述】:

这是我希望我的 ScrollView 的样子:

  • 最大尺寸是用layout_weight定义的(这样ScrollView下面的其他item才能正常显示)
  • 如果内容小于该最大大小,则它的行为与layout_height="wrap_content" 相同

这是我目前拥有的:

<ScrollView
            android:layout_height="wrap_content"
            android:layout_width="fill_parent"
            android:measureAllChildren="true"
            android:fillViewport="false"
            >

我不认为measureAllChildren 真的做任何事...

如果我添加android:layout_weight,大小将始终是我希望的最大值。没有它,它只会超出应有的范围......

如果需要的话,我不介意扩展 ScrollView 类来更改 onMeasure 的行为...?

PS:如果这会产生影响,我会尝试从 Froyo 开始进行这项工作。

【问题讨论】:

  • 为什么叫它“layout_weight”?不应该是“layout_max_height”之类的吗?

标签: android layout scrollview


【解决方案1】:

我最终编写了自己的类,扩展了 ScrollView

既然你问...这里是代码。可能不是最干净的,但它可以满足我的要求。

请注意,它希望在创建视图时设置 layout_weight 并且您不应该在父 LinearLayout 中设置 weigthSum 否则您会得到一些有趣的东西(因为这个权重从原始值变为 0 取决于关于 ScrollView 内容的大小)

首先,在布局文件中,视图是这样声明的:

<com.matthieu.widget.ShrinkingScrollView
    android:id="@+id/scroll"
    android:scrollbars="vertical"
    android:layout_height="0dp"
    android:layout_width="fill_parent"
    android:layout_weight="4"
    android:background="#cc0000"
    >
    <TextView
        android:id="@+id/in_scroll_view"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:background="#0000bb"
        />
</com.matthieu.widget.ShrinkingScrollView>

然后是小部件的代码:

import android.content.Context;
import android.util.AttributeSet;
import android.widget.LinearLayout;
import android.widget.ScrollView;

public class ShrinkingScrollView extends ScrollView {
    private float original_weight=-1;
    public ShrinkingScrollView(Context context) {
        super(context);
    }

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

    public ShrinkingScrollView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) getLayoutParams();
        float previous_weight = params.weight;

        if (original_weight == -1)
            original_weight = params.weight;

        if ((getChildCount()>0) && (getVisibility()!=GONE)) {
            super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0,MeasureSpec.UNSPECIFIED));
            int overall_height = getChildAt(0).getMeasuredHeight();
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            if (getMeasuredHeight() >= overall_height) {
                if (previous_weight != 0) {
                    params.weight=0;
                    params.height = overall_height;
                    setLayoutParams(params);
                    post(new Runnable() {
                        public void run() {
                            requestLayout();
                        }
                    });
                }

                setMeasuredDimension(getMeasuredWidth(),overall_height);
            }
            else if (previous_weight == 0) {
                params.weight = original_weight;
                params.height = 0;
                setLayoutParams(params);
                post(new Runnable() {
                    public void run() {
                        requestLayout();
                    }
                });
            }
        }
        else {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }
}

【讨论】:

  • 您本可以发布有关您的实施/解决方案的更多详细信息
  • 是否可以在 dp 中设置最大高度,而不是重量?如果有,怎么做?
  • 也许你想检查一下:stackoverflow.com/questions/4054567/…
【解决方案2】:

如果我正确理解了您的要求,那么我所做的事情就是将滚动视图与您想要在其下方显示的任何其他内容一起放置到相对布局中。然后,在您的布局文件中,首先将项目放在文件中的屏幕底部(使用 android:layout_alignParentBottom="true"),然后将滚动视图放在第一个项目上方,使用类似:android:layout_above= “@id/firstItem”。像这样,我在底部放置一个图像视图,在其上方有一个滚动视图,占用剩余空间:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/searchByNameScreen"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_gravity="center_horizontal"
    android:layout_marginTop="1dip"
    android:gravity="center_horizontal"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/bottomImage"
        android:layout_width="fill_parent"
        android:layout_height="75dip"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:paddingBottom="15dip"
        android:paddingLeft="10dip"
        android:paddingRight="10dip"
        android:paddingTop="7dip"
        android:scaleType="fitXY"
        android:src="@drawable/android_450x50_moreinfo" />

    <ScrollView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/ScrollView01"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_above="@id/bottomImage"
        android:layout_marginBottom="3dip"
        android:layout_marginLeft="10dip"
        android:layout_marginRight="10dip"
        android:layout_marginTop="1dip"
        android:scrollbars="none" >

        <LinearLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/aboutCopyLayout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/aboutTopLayer"
            android:layout_centerHorizontal="true"
            android:layout_gravity="center_horizontal"
            android:background="@drawable/rounded_background"
            android:gravity="center"
            android:padding="5dip" >

            <!-- android:background="@drawable/rounded_background" -->

            <TextView
                android:id="@+id/aboutCopyText"
                style="@style/ResortNameExtraLine"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:gravity="center_horizontal"
                android:text="@string/aboutCopy" />
        </LinearLayout>
    </ScrollView>
</RelativeLayout>

【讨论】:

  • 需要尝试一下...不过我有几个问题...看起来“方向”不适合 RelativeLayout 吗?我不希望 ScrollView 下方的内容位于屏幕底部……如果我也从上到下“填充”布局,它会起作用吗?我认为这可能是一个不错的选择,尽管我不能像在 LinearLayout 中那样使用任何权重
【解决方案3】:

这里是另一种使用尺寸而不是重量的解决方案。我扩展了 ScrollView 并添加了代码来实现这个功能:

https://gist.github.com/JMPergar/439aaa3249fa184c7c0c

希望对你有用。

【讨论】:

    【解决方案4】:

    JMpergar 的答案似乎是正确的,但直到我改变了 onMeasure 方法,如下所示。

     @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            try {
                int heightSize = MeasureSpec.getSize(heightMeasureSpec);
                if (maxHeight != WITHOUT_MAX_HEIGHT_VALUE
                        && heightSize > maxHeight) {
                    heightSize = maxHeight;
                    heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.AT_MOST);
                    getLayoutParams().height = heightSize;
    
                } else {
                    heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.AT_MOST);
                    setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec)
                            , getDefaultSize(this.getSuggestedMinimumHeight(), heightMeasureSpec));
                }
    
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            }
        }
    

    【讨论】:

      【解决方案5】:

      您可以将您的ScrollView 包裹到另一个ConstraintLayout,然后限制高度(app:layout_constrainedHeight="true" 行):

      <!-- another constraint layout to keep ScrollView shrinking -->
      <androidx.constraintlayout.widget.ConstraintLayout
          android:layout_width="match_parent"
          android:layout_height="wrap_content">
      
              <androidx.core.widget.NestedScrollView
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  app:layout_constrainedHeight="true"
                  app:layout_constraintTop_toTopOf="parent"
                  app:layout_constraintBottom_toBottomOf="parent">
      
                      <androidx.constraintlayout.widget.ConstraintLayout
                          android:id="@+id/content_layout"
                          android:layout_width="match_parent"
                          android:layout_height="wrap_content">
      

      【讨论】:

        猜你喜欢
        • 2012-01-31
        • 2019-04-22
        • 2012-03-19
        • 2019-07-31
        • 1970-01-01
        • 2012-06-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多