How to set a maximum height with wrap content in android?

前端 未结 7 2220
你的背包
你的背包 2020-12-09 02:01

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 trie

相关标签:
7条回答
  • 2020-12-09 02:32

    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);
    }
    
    0 讨论(0)
  • 2020-12-09 02:33

    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.

    0 讨论(0)
  • 2020-12-09 02:39

    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.

    0 讨论(0)
  • 2020-12-09 02:39

    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.

    0 讨论(0)
  • 2020-12-09 02:39

    I've extended ScrollView and added code to implement this feature:

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

    I hope that be useful.

    0 讨论(0)
  • 2020-12-09 02:47

    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.

    0 讨论(0)
提交回复
热议问题