【问题标题】:Android setWindowLayoutMode not working before SDK 11Android setWindowLayoutMode 在 SDK 11 之前不起作用
【发布时间】:2013-10-03 22:42:22
【问题描述】:

我正在尝试在 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" />

【问题讨论】:

    标签: android android-layout


    【解决方案1】:

    好吧,我从来没有找到解决 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);
    }
    

    【讨论】:

      猜你喜欢
      • 2022-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-10
      • 1970-01-01
      • 1970-01-01
      • 2018-05-22
      • 2022-01-03
      相关资源
      最近更新 更多