一.问题描述
<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);
本文探讨了如何在PopupWindow中使用ScrollView时,动态调整其高度以适应内容变化。当内容较少时,ScrollView应适应内容高度,内容较多时则保持固定高度并显示滚动条。由于ScrollView没有maxHeight属性,作者尝试了三种解决方案:一是通过测量LinearLayout的高度并手动设置ScrollView的高度,二是使用GlobalLayoutListener监听布局变化,三是自定义ScrollView并在onMeasure方法中限制高度。前两种方法存在误差或闪烁问题,第三种方法实现了预期效果,提供了可行的解决方案。
9608

被折叠的 条评论
为什么被折叠?



