Android全局弹窗dialog

终端开发总是会有这样的需求,无论在哪些场景下某种判断成立时候需要弹出通知比如网络断开等情况。类似这样的全局弹窗无非就是系统的dialog或者悬浮窗,悬浮窗的话需要用户开启悬浮窗权限,这里我就只提一下dialog的实现。这也是我在用的一种。

众所周知Android中dialog依赖于activity,所以要显示全局弹窗,最终问题就是获取最上面的activity对象,这就涉及到activity的管理,一般会有在base中建立activity列表维护所有activity,我们这边使用在application生命周期监听函数中处理。

首先这里有一个顶部activity管理的单例类:

public class TopActivityManager {
  private static final String TAG = "MyActivityManager";
  public static TopActivityManager instance = new TopActivityManager();
  private WeakReference currentActivityWeakRef;

  public TopActivityManager() {
  }

  public static TopActivityManager getInstance() {
    return instance;
  }

  public Activity getCurrentActivity() {
    Activity currentActivity = null;
    if (currentActivityWeakRef != null) {
      currentActivity = currentActivityWeakRef.get();
    }
    return currentActivity;
  }

  public void setCurrentActivity(Activity activity) {
    currentActivityWeakRef = new WeakReference(activity);
    LogMgr.d(TAG, currentActivityWeakRef.get().getClass().getSimpleName());
  }
}

然后就是调用set更新该对象的时机:

private void initLifeCycle() {
    registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
      @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
        LogMgr.d(TAG, "onActivityCreated");
        TopActivityManager.getInstance().setCurrentActivity(activity);
      }

      @Override public void onActivityStarted(Activity activity) {
        LogMgr.d(TAG, "onActivityStarted");
      }

      @Override public void onActivityResumed(Activity activity) {
        LogMgr.d(TAG, "onActivityResumed");
        TopActivityManager.getInstance().setCurrentActivity(activity);
      }

      @Override public void onActivityPaused(Activity activity) {
        LogMgr.d(TAG, "onActivityPaused");
      }

      @Override public void onActivityStopped(Activity activity) {
        LogMgr.d(TAG, "onActivityStopped");
       
      }

      @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
        LogMgr.d(TAG, "onActivitySaveInstanceState");
      }

      @Override public void onActivityDestroyed(Activity activity) {
        LogMgr.d(TAG, "onActivityDestroyed");
      }
    });
  }

这边可以看到在create和resume中都调用了set方法,resume调用是为了防止A启动B,B关闭后回到A的情况,在create时候设置是因为在有些情况进入页面oncreate里面就会做一些判断需要弹出全局弹窗,用到顶部activity,所以避免出错两个地方都进行设置。

这里再提供一份弹窗代码供测试

public class NetErrorDialog {
  private static final String TAG = "NetErrorDialog";
  private static NetErrorDialog instance;
  @BindView(R.id.tvCancel) TextView tvCancel;
  @BindView(R.id.tvNetSet) TextView tvNetSet;
  private MyDialog netErrorDialog;
  private NetHandler netHandler;

  public static NetErrorDialog getInstance() {
    if (instance == null) {
      synchronized (NetErrorDialog.class) {
        if (instance == null) {
          instance = new NetErrorDialog();
        }
      }
    }
    return instance;
  }

  private NetErrorDialog() {
    netHandler = new NetHandler();
  }

  public void showDialog() {
    if (netErrorDialog != null && netErrorDialog.isShowing()) {
      if (netErrorDialog.getContext() == TopActivityManager.getInstance().getCurrentActivity()) {
        return;
      } else {
        dismiss();
      }
    }
    netErrorDialog =
        new MyDialog(TopActivityManager.getInstance().getCurrentActivity(), R.style.DialogTheme);
    View dlgView = LayoutInflater.from(TopActivityManager.getInstance().getCurrentActivity())
        .inflate(R.layout.dlg_net_error, null);
    ButterKnife.bind(this, dlgView);
    netErrorDialog.setContentView(dlgView);
    netErrorDialog.setCancelable(false);

    Window window = netErrorDialog.getWindow();
    window.setGravity(Gravity.CENTER);
    window.setDimAmount(0f);
    window.setWindowAnimations(R.style.center_dialog_animStyle);
    window.setLayout(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    WindowManager.LayoutParams params = window.getAttributes();
    params.width = DisplayUtils.getInstance().dpToPx(340);
    params.height = DisplayUtils.getInstance().dpToPx(140);
    window.setAttributes(params);
    tvCancel.setOnClickListener(new View.OnClickListener() {
      @Override public void onClick(View v) {
        netErrorDialog.dismiss();
        if (netHandler != null) {
          netHandler.sendMsg();
        }
      }
    });

    tvNetSet.setOnClickListener(new View.OnClickListener() {
      @Override public void onClick(View v) {
        Intent wifiSettingsIntent = new Intent("android.settings.WIFI_SETTINGS");
        wifiSettingsIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        TopActivityManager.getInstance().getCurrentActivity().startActivity(wifiSettingsIntent);
      }
    });
    netErrorDialog.show();
  }

  public void dismiss() {
    if (netErrorDialog != null && netErrorDialog.isShowing()) {
      netErrorDialog.dismiss();
    }
  }

  public class NetHandler extends Handler {
    private static final int WHAT_NET_TIP = 0x222;

    @Override public void handleMessage(Message msg) {
      super.handleMessage(msg);
      if (msg.what == WHAT_NET_TIP) {
        if (!NetUtils.isNetworkAvailable()) {
          showDialog();
        } else {
          dismiss();
        }
      }
    }

    public void sendMsg() {
      LogMgr.d(TAG, "start send delay");
      sendEmptyMessageDelayed(WHAT_NET_TIP, 3 * 60 * 1000);
    }
  }

  public void release() {
    if (netErrorDialog != null) {
      if (netErrorDialog.isShowing()) {
        netErrorDialog.dismiss();
      }
      netErrorDialog = null;
    }
    instance = null;
  }
}

 

你可能感兴趣的:(Android全局弹窗dialog)