PopWindow 位置问题 Gravity.BOTTOM无效

目录

 

PopWindow位置问题 

Gravity.BOTTOM无效的原因

解决方案


 

PopWindow位置问题 

 

有时候我们通过PopWindow来从底部往上展示界面,可能会发现在部分机型上有问题,想要在bottom显示窗口,结果在top显示了,如下图:

 

Gravity.BOTTOM无效的原因


可能我们用的是下面这句代码:
popupWindow.showAtLocation(mRootLayout, Gravity.BOTTOM, 0, 0);在部分机型上有问题BOTTOM根本不管用

从源码中找答案,下面是部分源码

    //mGravity默认Gravity.NO_GRAVITY
    private int mGravity = Gravity.NO_GRAVITY;


    /**
     * <p>
     * Display the content view in a popup window at the specified location. If the popup window
     * cannot fit on screen, it will be clipped. See {@link android.view.WindowManager.LayoutParams}
     * for more information on how gravity and the x and y parameters are related. Specifying
     * a gravity of {@link android.view.Gravity#NO_GRAVITY} is similar to specifying
     * <code>Gravity.LEFT | Gravity.TOP</code>.
     * </p>
     *
     * @param parent a parent view to get the {@link android.view.View#getWindowToken()} token from
     * @param gravity the gravity which controls the placement of the popup window
     * @param x the popup's x location offset
     * @param y the popup's y location offset
     */
    public void showAtLocation(View parent, int gravity, int x, int y) {
        mParentRootView = new WeakReference<>(parent.getRootView());
        showAtLocation(parent.getWindowToken(), gravity, x, y);
    }


 /**
     * Display the content view in a popup window at the specified location.
     *
     * @param token Window token to use for creating the new window
     * @param gravity the gravity which controls the placement of the popup window
     * @param x the popup's x location offset
     * @param y the popup's y location offset
     *
     * @hide Internal use only. Applications should use
     *       {@link #showAtLocation(View, int, int, int)} instead.
     */
    public void showAtLocation(IBinder token, int gravity, int x, int y) {
        if (isShowing() || mContentView == null) {
            return;
        }

        TransitionManager.endTransitions(mDecorView);

        detachFromAnchor();

        mIsShowing = true;
        mIsDropdown = false;
        mGravity = gravity;

        final WindowManager.LayoutParams p = createPopupLayoutParams(token);
        preparePopup(p);

        p.x = x;
        p.y = y;

        invokePopup(p);
    }



    private int computeGravity() {
        int gravity = mGravity == Gravity.NO_GRAVITY ?  Gravity.START | Gravity.TOP : mGravity;
        if (mIsDropdown && (mClipToScreen || mClippingEnabled)) {
            gravity |= Gravity.DISPLAY_CLIP_VERTICAL;
        }
        return gravity;
    }

其实我们通过showAtLocation(mRootLayout, Gravity.BOTTOM, 0, 0)是想在bottom显示,但是部分机型有问题,这时候我们不要相信Gravity.BOTTOM的效果了,索性使用Gravity.NO_GRAVITY,后面传入自己计算好的坐标,一般x=0就好了,主要是计算y的值。

 

解决方案

 

popupWindow.showAtLocation(mRootLayout, Gravity.NO_GRAVITY, 0, DimenUtils.getWindowHeight() - contentView.getMeasuredHeight());

DimenUtils.getWindowHeight():屏幕的高度
contentView.getMeasuredHeight():内容view的高度(注意因为没有显示出来,所以view高度拿不到需要通过)

在使用getMeasuredHeight之前需要先测量一下
contentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);

private PopupWindow createPopupWindow(View contentView) {
        contentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
        PopupWindow popupWindow = new PopupWindow(contentView, WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT, true);
        popupWindow.setTouchable(true);
        popupWindow.setBackgroundDrawable(new BitmapDrawable());
        popupWindow.setFocusable(true);
        popupWindow.setAnimationStyle(R.style.PopupAnimation);
        popupWindow.setClippingEnabled(true);
        popupWindow.setSoftInputMode(PopupWindow.INPUT_METHOD_NEEDED);
        popupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
        popupWindow.showAtLocation(mRootLayout, Gravity.NO_GRAVITY, 0, DimenUtils.getWindowHeight() - contentView.getMeasuredHeight());

        popupWindow.update();
        return popupWindow;
    }

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RecyclerView可以通过Adapter实现数据的展示,但是如果需要在RecyclerView的item上弹出一个PopWindow,可以通过以下步骤实现: 1. 首先,在RecyclerView的Adapter中为item添加点击事件,例如: ```java public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> { ... public interface OnItemClickListener { void onItemClick(View view, int position); } private OnItemClickListener mOnItemClickListener; public void setOnItemClickListener(OnItemClickListener listener) { mOnItemClickListener = listener; } ... @Override public void onBindViewHolder(ViewHolder holder, final int position) { ... holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (mOnItemClickListener != null) { mOnItemClickListener.onItemClick(v, position); } } }); ... } ... public static class ViewHolder extends RecyclerView.ViewHolder { ... public ViewHolder(View itemView) { super(itemView); ... } } } ``` 2. 接下来,在Activity或Fragment中监听RecyclerView的item点击事件,并在点击事件中弹出PopWindow,例如: ```java myAdapter.setOnItemClickListener(new MyAdapter.OnItemClickListener() { @Override public void onItemClick(View view, int position) { View contentView = LayoutInflater.from(context).inflate(R.layout.pop_window_layout, null); // 初始化PopWindow final PopupWindow popupWindow = new PopupWindow(contentView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true); // 设置PopWindow位置 popupWindow.showAsDropDown(view); // 设置PopWindow的背景颜色 popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); // 设置PopWindow的动画效果 popupWindow.setAnimationStyle(R.style.AnimationFade); // 设置PopWindow是否可获取焦点 popupWindow.setFocusable(true); // 设置PopWindow是否可触摸 popupWindow.setTouchable(true); // 设置PopWindow外部是否可触摸 popupWindow.setOutsideTouchable(true); // 设置PopWindow的dismiss监听 popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() { @Override public void onDismiss() { // PopWindow消失后的操作 } }); } }); ``` 这样就可以在RecyclerView的item上弹出PopWindow了。需要注意的是,PopWindow位置可以通过showAsDropDown方法设置,可以根据实际需求进行调整。另外,PopWindow的布局可以通过布局文件进行自定义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值