Android开发:PopupWindow中ScrollView设置最大高度问题

一.问题描述

        <ScrollView
            android:id="@+id/pop_common_sl_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:overScrollMode="never">

            <LinearLayout
                android:id="@+id/pop_common_ll_container"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:paddingHorizontal="16dp" />
        </ScrollView>

这是PopupWindow布局文件中的部分代码,目的是实现LinearLayout中的子控件通过代码动态添加,当内容较少时,ScrollView适应内容高度,当内容较多时,ScrollView保持固定高度并显示滚动条。然而实现过程中发现ScrollView并没有提供maxHeight这个属性,导致显示出来的ScrollView在内容较多时撑满屏幕。

二.解决方法

方法一

在LinearLayout添加完子控件后,主动调用measure方法得出测绘高度,然后判断是否大于设置的高度值,大于的话就固定ScrollView的高度,代码如下:

        //LinearLayout测绘
        ui_ll_container.measure(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        //拿到测绘高度
        int height = ui_ll_container.getMeasuredHeight();
        //判断是否大于最大高度
        if (height > 500) {
            ViewGroup.LayoutParams layoutParams = ui_sl_container.getLayoutParams();
            layoutParams.height = 500;
            ui_sl_container.setLayoutParams(layoutParams);
        }

应用中发现主动去调用measure方法测绘出来的高度并不和最后显示出来相等,尤其是LinearLayout子控件包含TextView时相差很大,所以这种方法也只能适用于高度固定的子控件。

方法二

通过给LinearLayout控件注册GlobalLayoutListener,布局变化时在回调中获取高度,这样就能获取到显示的高度

        ui_ll_container.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                int height = ui_ll_container.getMeasuredHeight();
                if (height > 500) {
                    ViewGroup.LayoutParams layoutParams = ui_sl_container.getLayoutParams();
                    layoutParams.height = 500;
                    ui_sl_container.setLayoutParams(layoutParams);
                }
                //移除监听器 避免多次调用
                ui_ll_container.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            }
        });

测试中发现高度没错,但显示出来的布局高度发生改变会造成页面出现闪烁的情况。

方法三(可行)

自定义ScrollView,重写onMeasure方法。布局中ScrollView改为MyScrollView,通过代码来设置最大高度

public class MyScrollView extends ScrollView {
    public static final String TAG = "MyScrollView";
    private int maxHeight = -1;

    public MyScrollView(Context context) {
        super(context);
    }

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

    public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int height = getMeasuredHeight();
        int width = getMeasuredWidth();
        if (maxHeight > 0 && height > maxHeight) {
            setMeasuredDimension(width, maxHeight);
        }
    }

    public void setMaxHeight(int height) {
        this.maxHeight = height;
    }
}
MyScrollView ui_sl_container = view.findViewById(R.id.pop_common_sl_container);
ui_sl_container.setMaxHeight(500);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

开发大观园

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值