Android Android scrolling scheme (wrap_content, maximum size)

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

  • The maximum size is determined using layout_weight (so that other elements under the ScrollView can display correctly)
  • If the content is smaller than this maximum size, it just behaves like with layout_height="wrap_content"

Here is what I have now:

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

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

If I add android:layout_weight , the size will always be what I would like to be maximum. Without it, it simply expands more than necessary ...

Do I mind extending the ScrollView class to change the behavior of onMeasure if I need ...?

PS: If that makes a difference, I'm trying to get it to work from Froyo forward.

+4
source share
4 answers

I ended up writing my own class, expanding ScrollView

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

Note that it expects layout_weight to be set when the view is created, and you don’t have to set weigthSum in the parent LinearLayout or you will get funny things (since the weight of this changes from the original value to 0 depending on the size of the contents of the ScrollView)

First, in a layout file, a view is declared as follows:

 <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 widget code:

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

If I understand your requirement correctly, then, as I did something like this, you need to put scrollview along with anything else that you want to display under it in the Relative layout. Then in your layout file, first place the element at the bottom of the screen into a file (with android: layout_alignParentBottom = "true"), then place the scroll view and place it above the first element using something like: android: layout_above = "@ id / firstItem ". Like this, in which I put the image at the bottom with a scroll view above it, occupying 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> 
0
source

Here's another solution using dimensions instead of weights. I expanded ScrollView and added code to implement this function:

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

I hope this will be helpful.

0
source

JMpergar's answer seems to be correct, but it did not work until I changed the onMeasure method as shown 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); } } 
0
source

Source: https://habr.com/ru/post/1398500/


All Articles