1

我正在尝试在 Android 中创建一个 PopupWindow,它以显示的中间为中心,并根据加载的视图的内容动态调整大小。此外,弹出窗口之外的任何点击都应关闭弹出窗口。在 SDK 版本 11 中,此代码运行良好,但在 SDK 10(我们的应用程序必须支持的最低版本)中,setWindowLayoutMode 似乎什么都不做。

到目前为止,我已经对这个逻辑进行了子类化,这对我来说似乎很干净和高效,除了 SDK 10 的问题(错误?)。关于我做错了什么有什么想法吗?我看到 setWindowLayoutMode 自第 3 版以来一直存在,所以我很难相信它根本无法像文档中描述的那样工作。如果是 SDK 错误,我该如何解决该问题?我在 contentView 上尝试了 .measure() ,将屏幕尺寸作为限制,目的是手动设置窗口大小,但它返回的值与预期结果大不相同。

通过将 TextView 包装在可以设置为与屏幕尺寸匹配的布局中,我可以轻松地使窗口居中,但随后我失去了不错的 ACTION_OUTSIDE 轻击事件,所以如果可以避免的话,我宁愿不跌倒这条路。

我应该提到,SDK 10 上发生的问题是窗口根本没有出现......它在技术上“出现”,尺寸为 0,0 或屏幕外,因为随后的点击会触发 OnTouchListener,但它肯定没有正确显示其内容。

public class InfoPopupWindow extends PopupWindow {
    private View _parentView;

    public InfoPopupWindow(Context context, View parentView) {
        super(context);

        LayoutInflater inflater = LayoutInflater.from(context);
        View contentView = inflater.inflate(R.layout.window_info, null, false);
        this.setContentView(contentView);

        this.setWindowLayoutMode(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);

        // This combo of parameters sends outside events properly, and inside events as well.
        this.setOutsideTouchable(true);
        this.setBackgroundDrawable(new BitmapDrawable());
        this.setTouchInterceptor(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
                    Log.d("InfoPopupWindow", "Outside Window Touch Event");
                    dismiss();
                }
                return true;
            }
        });

        this.setAnimationStyle(R.style.PopupAnimation);

        _parentView = parentView;
    }

    public void show() {
        this.showAtLocation(_parentView, Gravity.CENTER, 0, 0);
    }
}

R.layout.window_info

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/info_text"
    android:id="@+id/textView"
    android:background="#000000"
    android:padding="15dp" />
4

1 回答 1

0

好吧,我从来没有找到解决 setWindowLayoutMode 损坏的方法,但是我能够从构造函数中调用此方法来获取 API 10 以正确调整弹出窗口的大小。解决方法是我之前测试过的一种,但我一直在滥用 MeasureSpec 参数。希望有一天这可以帮助其他人......

private void calculateAndSetContentViewSize(Context context, View contentView) {
    WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Display display = windowManager.getDefaultDisplay();

    int screenWidth, screenHeight;

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB_MR2) {
        Point windowSize = new Point();
        display.getSize(windowSize);
        screenWidth = windowSize.x;
        screenHeight = windowSize.y;
    } else {
        screenWidth = display.getWidth();
        screenHeight = display.getHeight();
    }

    int widthSpec = View.MeasureSpec.makeMeasureSpec(screenWidth, View.MeasureSpec.EXACTLY);
    int heightSpec = View.MeasureSpec.makeMeasureSpec(screenHeight, View.MeasureSpec.UNSPECIFIED);

    contentView.measure(widthSpec, heightSpec);
    this.setWidth(contentView.getMeasuredWidth());
    this.setHeight(contentView.getMeasuredHeight());

    this.setWindowLayoutMode(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
于 2013-10-03T14:42:22.727 回答