记一次PopupWindow内部View高度测量问题

2022-07-21  本文已影响0人  二贝呀

先抛出问题

因为布局排版原因,TextView并不能完全展示其内容,所以出现此需求:点击TextView在其上方出现一个气泡背景来展示其内容。
本来想着很简单的一个需求,首先想到了PopiWindow,用PopuWindow的showAtLocation()去实现,写出了如下代码。

LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View inflate = layoutInflater.inflate(R.layout.popupwindow_layout, null);
TextView tv_Content = (TextView) inflate.findViewById(R.id.tv_Content);
PopupWindow popupWindow = new PopupWindow(inflate, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
tv_Content.setText(content);
popupWindow.setFocusable(true);
popupWindow.setOutsideTouchable(true);
// 这个是为了点击“返回Back”也能使其消失,并且并不会影响你的背景
popupWindow.setBackgroundDrawable(new BitmapDrawable());
int[] location = new int[2];
//getLocationOnScreen()此函数可以获取到View所在视图的绝对坐标点,并将获取到的坐标点存放到一个int数组中
view.getLocationOnScreen(location);

popupWindow.showAtLocation(view, Gravity.NO_GRAVITY, location[0],location[1] - tv_Content.getHeight());

本以为如此简单,结果发现

popupWindow.showAtLocation(view, Gravity.NO_GRAVITY, location[0],location[1] - tv_Content.getHeight());

并未生效(Y轴坐标未生效)想到肯定是这里出的问题

location[1] - tv_Content.getHeight()

因为这是控制PopuWindow将要出现在Y轴的具体位置,所以想着肯定是

tv_Content.getHeight()没获取到准确高度

好了,现在知道问题了,那么直接通过post()函数去获取到tv_Content的高度不就行了嘛,此时代码如下:

tv_Content.post(new Runnable() {
    @Override
    public void run() {
        mHeight = tv_Content.getMeasuredHeight();
        Log.e("TAG","post>>>>" + height);
    }
});
popupWindow.showAtLocation(view, Gravity.NO_GRAVITY, location[0],location[1] - mHeight);

此时发现效果跟之前没啥变化,但是log打印的height是正确的,想着应该是PopuWindow先show后,才获取到的height,所以没变化,那好吧我把PopuWindow放在post里面show总行了吧。

tv_Content.post(new Runnable() {
    @Override
    public void run() {
        int height = tv_Content.getMeasuredHeight();
        Log.e("TAG","post>>>>" + height);
         popupWindow.showAtLocation(view, Gravity.NO_GRAVITY,
                    location[0],location[1] - height);
    }
});

此时发现效果还是没变化,而且离奇的事情发生了log打印出height的值为0,这是为啥呢?之前还能获取到的高度这次怎么获取不到了?于是经过两个小时的测试最终发现。。。。

PopupWindow未show之前,其内部的View是获取不到宽高的。

于是最终修改为:

tv_Content.post(new Runnable() {
    @Override
    public void run() {
        int height = tv_Content.getMeasuredHeight();
        Log.e("TAG","post>>>>" + height);
        if (popupWindow.isShowing()){
            popupWindow.dismiss();
            tv_Content.setVisibility(View.VISIBLE);//此时让其显示出来
            popupWindow.showAtLocation(view, Gravity.NO_GRAVITY,
                    location[0],location[1] - height);
        }
    }
});
//PopuWindow第一次show(注意:tv_Content我默认是invisible,所以第一次其实用户是看不到popu的)
popupWindow.showAtLocation(view, Gravity.NO_GRAVITY, location[0],location[1]);

好了,结束。下班!!!

上一篇 下一篇

猜你喜欢

热点阅读