如何允许PopupWindows将内容包装到最大首选大小?

时间:2018-02-28 14:36:55

标签: android

我有一个广泛使用PopupWindows的Android应用程序。我发现当PopupWindow内容的布局使用WRAP_CONTENT时,对话框在开始截断内容之前只会增长到特定的宽度。我已将其追溯到config.xml维度:

<dimen name="config_prefDialogWidth">580dp</dimen>

此尺寸用于在确定对话框大小时在ViewRootImpl的measureHierarchy方法中创建最大宽度。以下代码用于访问值:

final DisplayMetrics packageMetrics = res.getDisplayMetrics();
res.getValue(com.android.internal.R.dimen.config_prefDialogWidth, mTmpValue, true);
int baseSize = 0;
if (mTmpValue.type == TypedValue.TYPE_DIMENSION) {
    baseSize = (int)mTmpValue.getDimension(packageMetrics);
}

config_prefDialogWidth似乎具有不同设备配置的值,例如,我列出的是sw600dp。默认设备的设备值为320dp。

看起来这个尺寸是针对纵向调整的。由于我的app强制横向,因此宽度太小。

如何覆盖config_prefDialogWidth维度?

2 个答案:

答案 0 :(得分:0)

您需要的是使PopupWindow(wrap_content)的宽度大于config_prefDialogWidth。

所以这是我的解决方案。

从PopupWindow的contentView中选择一个子视图。

例如,

TextView。

覆盖其onMeasure,必要时添加View.MEASURED_STATE_TOO_SMALL

        TextView textView = new TextView(context) {
        @Override
        protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            // Text breaks into at least 2 lines, maybe the width is too small
            if (getLineCount() > 1) {
                int measuredWidth = getMeasuredWidth();
                final int desiredMaxWidth = (getResources().getDisplayMetrics().widthPixels >> 2) * 3;
                // Compare with the desired max width you want, for example: 3/4 * screenWidth
                if (measuredWidth < disiredMaxWidth) {
                    // Tell ViewRootImpl that the width used to measure is too small
                    measuredWidth |= View.MEASURED_STATE_TOO_SMALL;
                    // ViewRootImpl will remeasure contentView with screem width.
                    setMeasuredDimension(measuredWidth, getMeasuredHeight());
                }
            }
        }
    };

一般来说:

  1. 覆盖一个孩子的onMeasure查看

  2. 检查测量宽度是否太小

  3. 如有必要,请求重新测量(使用View.MEASURED_STATE_TOO_SMALL

答案 1 :(得分:0)

您无法覆盖或更改PopupWindows的值,因为此维度是内部资源。解决方法是您必须创建自己的类。您可以从其源代码中复制{{1}},然后对其进行修改。