弹出窗口在屏幕底部被截断

3

当PopupWindow接近屏幕底部时,它的填充正常,但被截断。 有人知道我如何在弹出窗口靠近屏幕底部时使其向上填充吗?

enter image description here

public SelectBucketMenu(Context context) {
        super(context);
        this.mContext = context;

        setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        setOutsideTouchable(true);
        setFocusable(true);
        //Need set windowlayout for API 19 otherwise window won't appear
        setWindowLayoutMode(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);

        setupView();
    }

    private void setupView(){
        View view = LayoutInflater.from(mContext)
                .inflate(R.layout.popupmenu_selectbucket, null);
        ButterKnife.bind(this, view);
        setContentView(view);
    }

有人知道为什么吗?

3个回答

4

测量视图并设置高度,解决了我的问题。

View view = LayoutInflater.from(mContext).inflate(R.layout.popupmenu_addphotos, null);

view.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
setHeight(view.getMeasuredHeight());

它能在API 19上运行吗?我测试过了,但不起作用。我的意思是弹出窗口没有出现。 - Mir Milad Hosseiny
是的,它在我的API 19真实设备上运行。你是否将它放置在setContentView(view);之前? - DIRTY DAVE
我之前在 setContentView(view); 之前做了,但仍然不起作用。我在模拟器上测试过了。你能否完整地分享你的代码? - Mir Milad Hosseiny
我找到了问题所在。我不知道为什么即使在API 29上,view.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); 对我来说也不起作用,但是 int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); view.measure(spec, spec); 却很好用。 - Mir Milad Hosseiny

1

这就是我在 Kotlin 中解决问题的方法

    val view =inflater.inflate(R.layout.layout_certificate_context_menu,null)
    val spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
    view.measure(spec, spec)
    val popupWindow = PopupWindow(view, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true)

    popupWindow.height = view.measuredHeight
    popupWindow.elevation = 3.pxF

    iv_menu.setOnClickListener {
        popupWindow.showAsDropDown(it)
       
    }

这是正确的方式。setWindowLayoutMode()已经被弃用,而且对我来说甚至都没有起作用。 - Barry Fruitman

0

我替换了以下行

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

使用

setWindowLayoutMode(ViewGroup.LayoutParams.WRAP_CONTENT, 0);

通过调用 setHeight 方法设置弹出窗口的高度。

最终代码如下:

public SelectBucketMenu(Context context) {
    super(context);
    this.mContext = context;

    setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
    setOutsideTouchable(true);
    setFocusable(true);
    //Need set windowlayout for API 19 otherwise window won't appear
    setWindowLayoutMode(ViewGroup.LayoutParams.WRAP_CONTENT, 0);
    setHeight((int)mContext.getResources().getDimension(R.dimen.bucket_menu_height));
    setupView();
}

更新
如果您需要在运行时计算弹出窗口的高度,您可以在这个答案中找到想法。然后最终的代码可能如下所示:

public SelectBucketMenu(Context context) {
    super(context);
    this.mContext = context;

    setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
    setOutsideTouchable(true);
    setFocusable(true);
    //Need set windowlayout for API 19 otherwise window won't appear
    setWindowLayoutMode(ViewGroup.LayoutParams.WRAP_CONTENT, 0);

    setupView();
}

private void setupView(){
    View view = LayoutInflater.from(mContext)
                .inflate(R.layout.popupmenu_selectbucket, null);
    ButterKnife.bind(this, view);
    setContentView(view);

    int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec. UNSPECIFIED);
    view.measure(spec, spec);
    setHeight(view.getMeasuredHeight());
}

更新2
以下代码无用,可以删除。

setWindowLayoutMode(ViewGroup.LayoutParams.WRAP_CONTENT, 0);

尝试过了,仍然被裁剪在屏幕底部。https://i.imgur.com/iYH2ddO.png - DIRTY DAVE
nav_header_height是你的弹出窗口的高度吗? - Mir Milad Hosseiny
如何获取“view”的高度而不是使用定义的尺寸高度?View view = LayoutInflater.from(mContext) .inflate(R.layout.popupmenu_addphotos, null); - DIRTY DAVE
我使用的方法不需要额外的行来在API 19上工作。setWindowLayoutMode(ViewGroup.LayoutParams.WRAP_CONTENT, 0);但是我会给你赏金。 - DIRTY DAVE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接