版權聲明:本文為xing_star原創文章,轉載請注明出處!
本文同步自http://javaexception.com/archives/108
PopupWindow陰影覆蓋問題
最近這段時間需求不是很多,就有時間解決下之前遺留的小尾巴,比如PopWindow在某些特殊手機上陰影無法覆蓋底部,看起來總覺得怪怪的,最近用全面屏手機相對較多,看到這種情況就更加顯眼了,強迫症的我立刻動手Fix這個問題。只記得之前是PopWindow是在Android N以上設備顯示有問題,記得還是一兩年前吧,那個時候還沒怎么有全面屏手機的問題。在網上搜了下關於處理全面屏顯示PopWindow的問題,找到了想要的答案。
本文以一個完整的sample,描述popWindow在紅米6Pro這樣的全面屏手機上的使用。
案例描述:
創建一個BasePopWindow類,作為PopWindow的基類。
public abstract class BasePopWindow extends PopupWindow { private final View content; protected Activity context; public BasePopWindow(Activity context) { super(context); this.context = context; LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); content = inflater.inflate(getLayoutId(), null); this.setContentView(content); this.setWidth(ViewGroup.LayoutParams.MATCH_PARENT); this.setHeight(ViewGroup.LayoutParams.MATCH_PARENT); this.setFocusable(true); this.setOutsideTouchable(true); this.update(); ColorDrawable dw = new ColorDrawable(Color.parseColor("#80000000")); this.setBackgroundDrawable(dw); findAllView(content); initListener(); } protected abstract void findAllView(View view); protected abstract int getLayoutId(); protected abstract void initListener(); }
寫一個簡單的業務PopWindow,這里只是演示,就弄的比較簡單。
public class CustomPopWindow extends BasePopWindow { public CustomPopWindow(Activity context) { super(context); } @Override protected void findAllView(View view) { } @Override protected int getLayoutId() { return R.layout.popwindow_select; } @Override protected void initListener() { } public void showPopupWindow(View anchor) { if (!this.isShowing()) { show(anchor); } else { this.dismiss(); } } private void show(View anchor) { if (Build.VERSION.SDK_INT >= 24) { Rect rect = new Rect(); anchor.getGlobalVisibleRect(rect); int height; if (ScreenUtils.isShowNavBar(context)) { height = anchor.getResources().getDisplayMetrics().heightPixels - rect.bottom; } else { height = ScreenUtils.getRealHeight(context) - rect.bottom; } setHeight(height); } this.showAsDropDown(anchor, 0, 0); } }
我們只關注show方法,里面特意判斷了是Android N以上的設備,另外又針對Android N以上設備區分了是否是顯示了導航欄,這個說法也是別人寫的,我的理解是通過計算屏幕高度,真實高度,來判斷應該給PopWindow設置多少的高度。這塊為何要按照這個邏輯寫,我並沒有深入研究源碼,先滿足需求,有時間有條件在深究了。
在MainActivity中響應頁面事件。
public class MainActivity extends AppCompatActivity { TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = findViewById(R.id.text_view); textView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { CustomPopWindow popWindow = new CustomPopWindow(MainActivity.this); popWindow.showPopupWindow(v); } }); } }
還有部分代碼未貼出,在源碼中給出,點擊原文地址獲取源碼。
其他資料參考:
PopUpWindow在Android7.0及以上位置和陰影顯示問題 https://www.jianshu.com/p/6d8bd97c0e82
Github開源項目BasePopup https://github.com/razerdp/BasePopup