android ScrollView layout (wrap_content, maximum size)

天涯浪子 提交于 2019-12-23 12:52:34

问题


Here is what I would like my ScrollView to look like:

  • The maximum size is defined with the layout_weight (so that other items below the ScrollView can be displayed properly)
  • If the content is smaller than that maximum size, then it just behaves as with layout_height="wrap_content"

Here is what I currently have:

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

I don't think the measureAllChildren really does anything at all...

If I add android:layout_weight, the size will always be what I would like the maximum to be. Without it, it just extends more than it should...

I don't mind extending the ScrollView class to change the behavior of onMeasure if I need to...?

PS: If that makes a differences, I am trying to get this working from Froyo onward.


回答1:


I ended up writing my own class, extending ScrollView

Since you ask...here is the code. Probably not the cleanest but it does what I want.

Note that it expects the layout_weight to be set when the view is created and you should not set the weigthSum in the parent LinearLayout or you'll get funny things (since the weight of this one changes from the original value to 0 depending on the size of the content of the ScrollView)

First, in the layout file, the view is declared like this:

<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>

Then the code for the widget:

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);
        }
    }
}



回答2:


If I understand your requirement correctly, the way I have done something like this is to place the scrollview along with anything else you want to display below it into a Relative layout. Then, in your layout file place the item on the bottom of the screen in the file first (with android:layout_alignParentBottom="true"), then put the scroll view and place it above the first item using something like:android:layout_above="@id/firstItem". Like this in which I put an image view on the bottom with a scroll view above it taking the remaining space:

<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>



回答3:


Here another solution using sizes instead of weights. I've extended ScrollView and added code to implement this feature:

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

I hope that be useful.




回答4:


JMpergar answer seems right but its not worked until I changed the onMeasure method like below.

 @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);
        }
    }


来源:https://stackoverflow.com/questions/9457194/android-scrollview-layout-wrap-content-maximum-size

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!