1. 程式人生 > >不用WindowManger顯示全域性懸浮窗

不用WindowManger顯示全域性懸浮窗

       Android7.1、Android8.0對WindowManager的限制越來越多, 想顯示個SYSTEM_ALERT型別的window需要使用者授權, 不同安卓版本可以使用TYPE_PHONE、TYPE_TOAST、TYPE_SYSTEM_OVERLAY型別, 但國內各廠商手機對懸浮窗可能單獨做處理,執行時可能出現各種坑。

       比如有個需求, 應用的各個介面都要顯示個懸浮按鈕, 點選後退出應用(效果類似於從今日頭條開啟京東商城,每個介面都有“返回頭條”)。 

    做法是在監聽每個activity的生命週期,在onCreate函式執行後再新增一個子View, 從而並不破壞每個activity的邏輯;

public class MyApplication extends Application {
  @Override public void onCreate() {
    super.onCreate();
    initLifyCycle();
  }

  private void initLifyCycle() {
    this.registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
      @Override public void onActivityCreated(final Activity activity, Bundle bundle) {
        View view = LayoutInflater.from(activity)
            .inflate(R.layout.layout_window_alert, null);
        FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT);
        layoutParams.topMargin = 300;
        layoutParams.leftMargin = 0;

        view.setOnClickListener(new View.OnClickListener() {
          @Override public void onClick(View view) {
            Intent intent = new Intent(activity, MainActivity.class);
            intent.putExtra("fromBaidu", true);
            activity.startActivity(intent);
          }
        });
        ((FrameLayout) activity.getWindow().getDecorView()).addView(view, layoutParams);
      }

 如果看Activity的setContentView函式, 其實就是在mDecor裡新增View, 而mDecor繼承於FrameLayout類。