Reputation: 43833
In android, how can you create a scroll view that's got a max height, and wrap contents, basically it wraps the content vertically, but has a maximum height?
I tried
<ScrollView
android:id="@+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxHeight="200dp"
android:layout_alignParentBottom="true" >
<LinearLayout
android:id="@+id/maincontainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
</ScrollView>
But this isn't working?
Upvotes: 39
Views: 54668
Reputation: 1831
Some modification of harmashalex answer, I can pass desired max height for any view :
import android.view.View;
import android.view.ViewTreeObserver;
public class MaxHeightForAnyView implements ViewTreeObserver.OnGlobalLayoutListener{
private int maxHeight = 130;
private View view;
public MaxHeightForAnyView(View view, int maxHeight) {
this.view = view;
this.maxHeight = maxHeight ;
}
@Override
public void onGlobalLayout() {
if (view.getHeight() > maxHeight)
view.getLayoutParams().height = maxHeight;
}
}
And just set the listener to any view in oncreate with desired height :
txtShowTrans.getViewTreeObserver().addOnGlobalLayoutListener(new MaxHeightForAnyView(txtShowTrans, 600));
Upvotes: 0
Reputation: 40522
It can be done by wrapping the view into ConstraintLayout and using layout_constraintHeight_max
attribute.
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="200dp">
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHeight_max="wrap"
app:layout_constraintVertical_bias="0">
...
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
In the example above, the parent ConstraintLayout
height is limited to 200dp
, and the child ScrollView
height wraps the content till it's less than 200dp
. Note that app:layout_constraintVertical_bias="0"
aligns the child ScrollView
at the top of the parent, otherwise it will be centered.
Upvotes: 7
Reputation: 3576
1.) Create a class to handle setting maximum height to what is passed by the user:
public class OnViewGlobalLayoutListener implements ViewTreeObserver.OnGlobalLayoutListener {
private Context context;
private int maxHeight;
private View view;
public OnViewGlobalLayoutListener(View view, int maxHeight, Context context) {
this.context = context;
this.view = view;
this.maxHeight = dpToPx(maxHeight);
}
@Override
public void onGlobalLayout() {
if (view.getHeight() > maxHeight) {
ViewGroup.LayoutParams params = view.getLayoutParams();
params.height = maxHeight;
view.setLayoutParams(params);
}
}
public int pxToDp(int px) {
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
int dp = Math.round(px / (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
return dp;
}
public int dpToPx(int dp) {
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
int px = Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
return px;
}
}
2.) Attach this to the view and pass the maximum height in DP:
messageBody.getViewTreeObserver()
.addOnGlobalLayoutListener(
new OnViewGlobalLayoutListener(messageBody, 256, context)
);
Thanks to @harmashalex for the inspiration. I made modifications to as setting the layout params didn't work by @harma's code. Also, dp-to-px conversion is necessary to offload wondering about it.
Upvotes: 0
Reputation: 250
You can do it programmatically.
private static class OnViewGlobalLayoutListener implements ViewTreeObserver.OnGlobalLayoutListener {
private final static int maxHeight = 130;
private View view;
public OnViewGlobalLayoutListener(View view) {
this.view = view;
}
@Override
public void onGlobalLayout() {
if (view.getHeight() > maxHeight)
view.getLayoutParams().height = maxHeight;
}
}
And add listener to the view:
view.getViewTreeObserver()
.addOnGlobalLayoutListener(new OnViewGlobalLayoutListener(view));
Listener will call method onGlobalLayout(), when view height will be changed.
Upvotes: 21
Reputation: 55
for set scrollview height you must use 2 linerlayout inside together and then set scrool view as them child then set middle linerlayout layout:height for limit scrollview height.
Upvotes: 0
Reputation: 4844
you can add this to any view (override onMeasure in a class inherited from a view)
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (maxHeight > 0){
int hSize = MeasureSpec.getSize(heightMeasureSpec);
int hMode = MeasureSpec.getMode(heightMeasureSpec);
switch (hMode){
case MeasureSpec.AT_MOST:
heightMeasureSpec = MeasureSpec.makeMeasureSpec(Math.min(hSize, maxHeight), MeasureSpec.AT_MOST);
break;
case MeasureSpec.UNSPECIFIED:
heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST);
break;
case MeasureSpec.EXACTLY:
heightMeasureSpec = MeasureSpec.makeMeasureSpec(Math.min(hSize, maxHeight), MeasureSpec.EXACTLY);
break;
}
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
Upvotes: 36
Reputation: 1906
I've extended ScrollView and added code to implement this feature:
https://gist.github.com/JMPergar/439aaa3249fa184c7c0c
I hope that be useful.
Upvotes: 22
Reputation: 301
Here you can set height of your Scrollview like this -:
<ScrollView
android:id="@+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_alignParentBottom="true" >
<LinearLayout
android:id="@+id/maincontainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
</ScrollView>
Upvotes: -7