1. 程式人生 > >PopupWindow在Android7.0和7.1系統上顯示位置不正確的問題解決

PopupWindow在Android7.0和7.1系統上顯示位置不正確的問題解決

前言

今天做專案需要用到PopupWindow,但發現其顯示的位置在Android7.0以下系統正常,在7.0和7.1系統顯示不正常,點選“開啟POP”按鈕效果對比如下:

4.1系統


7.0系統


7.1系統


程式碼如下:

public class MainActivity extends AppCompatActivity {

    private LinearLayout popupDisplay;
    private PopupWindow popupWindow;
    private Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        popupDisplay = (LinearLayout) UiUtil.inflate((R.layout.popup));
        popupWindow = new PopupWindow(popupDisplay, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, true);
        popupWindow.setTouchable(true);
        popupWindow.setOutsideTouchable(true);
        popupWindow.setBackgroundDrawable(new BitmapDrawable(getResources(), (Bitmap) null));

        button = (Button) findViewById(R.id.btn);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                popupWindow.showAsDropDown(button);
            }
        });
    }
}

原因

解決

看了許多關於PopupWindow的bug的相關文章,分享如下

方案一:

自定義一個類繼承PopupWindow,重寫構造方法和需要用到的showAsDropDown()方法

public class SFPopupWindow extends PopupWindow {

    public SFPopupWindow(Context context) {
        super(context, null);
    }

    @Override
    public void showAsDropDown(View anchor) {
        if (Build.VERSION.SDK_INT == 24) {
            Rect rect = new Rect();
            anchor.getGlobalVisibleRect(rect);
            int h = anchor.getResources().getDisplayMetrics().heightPixels - rect.bottom;
            setHeight(h);
        }
        super.showAsDropDown(anchor);
    }
}
參考連結:http://blog.csdn.net/ithouse/article/details/56853948
方案二:

直接在需要顯示的地方判斷顯示的方式

if (Build.VERSION.SDK_INT == 24) {
    int[] a = new int[2];
    m.get().getLocationInWindow(a);
    popupWindow.showAtLocation(getWindow().getDecorView(), Gravity.NO_GRAVITY, 0, a[1]);
    popupWindow.update();
} else {
    popupWindow.showAsDropDown(v, 0, -Utils.dip2px(46));
}
參考連結:http://blog.csdn.net/m190607070/article/details/58618662

方案三:

使用showAtLocation()顯示

Android 7.0之前,在指定位置彈出popupwindow可以用showAsDropDown(View anchor, int xoff, int yoff),showAtLocation(View parent, int gravity, int x, int y)。但在android 7.0上,用showAsDropDown()在popupwindow為全屏時,會有彈出位置異常情況,需用showAtLocation()才能正常顯示:

if (Build.VERSION.SDK_INT < 24)
        {
            dropListPopupWindow.showAsDropDown(this, 0, 5);
        }
        else
        {
            // 適配 android 7.0
            int[] location = new int[2];
            getLocationOnScreen(location);
            int x = location[0];
            int y = location[1];
            Log.e(getClass().getSimpleName(), "x : " + x + ", y : " + y);
            dropListPopupWindow.showAtLocation(this, Gravity.NO_GRAVITY, 0, y + getHeight() + 5);
        }
參考連結:http://blog.csdn.net/dxxs19/article/details/53572833

通過上述方案修正後,在7.1上測試如圖