How to Realize Pop up Sequence Priority Control in Android

  • 2021-12-12 05:39:43
  • OfStack

1 Generally, in the homepage of the project, there are often multiple dialog boxes that need to pop up, such as active pop-up window, update pop-up window, scoring pop-up window, etc., and these pop-up windows have priority order. These pop-up windows 1 are generally displayed after returning results through interface requests. If only a few pop-up windows are easy to handle, it is OK to judge one after another in business logic. If there are more than 10 or more, it will be very troublesome to deal with, and it is prone to problems.

Therefore, it is very necessary to package a pop-up function that can be displayed in priority order. First, the functional requirements are as follows:

Blocking display of various types of pop-up windows according to priority order, starting from the highest priority by default Only when the previous high-priority pop-up window is displayed or cancelled, the next low-priority pop-up window can be displayed The premise of specifying to display a certain 1 pop-up window is that there are no higher priority pop-up windows to display Before displaying 1 pop-up window, it is necessary to judge whether it can or needs to be displayed Find the specified pop-up window according to the priority, which is equivalent to only 1ID Pop-up windows include many types, such as Dialog, PopupWindow, Activity and so on

Then start coding to achieve the function, first set an enumeration class, list the supported pop-up types, including Dialog, PopupWindow, Activity and so on.


public enum WindowType {

  DIALOG,
  POUPOWINDOW,
  TOAST,
  SNACKBAR,
  WIDGET,
  ACTIVITY,
  OTHERS

}

Then define the pop-up interface IWindow, which defines the basic functions of the pop-up window.


/**
*  Window contract rules 
*/
public interface IWindow {

  /**
   *  Pop-up display 
   */
  void show(Activity activity);

  /**
   *  Pop-up window closed 
   */
  void dismiss();

  /**
   *  Set the window to close listening 
   */
  void setOnWindowDismissListener(OnWindowDismissListener listener);

  /**
   *  Set up window display monitoring 
   */
  void setOnWindowShowListener(OnWindowShowListener listener);

}

And pop-up display and closed monitoring interface,


/**
*  Window closing listening 
*/
public interface OnWindowDismissListener {

  /**
   *
   */
  void onDismiss();

}

/**
*  Window display monitoring 
*/
public interface OnWindowShowListener {

  void onShow();

}

Next, define a wrapping class WindowWrapper to encapsulate the attributes and states related to pop-up windows, including pop-up windows, priority, whether they can be displayed, form types, etc., which will be used when processing pop-up display logic.


/**
*  Window parameter class 
*/
public class WindowWrapper {

  /**
   *  Window 
   */
  private IWindow mWindow;

  /**
   *  Priority, the higher the value, the higher the priority 
   */
  private int mPriority;

  /**
   *  Is currently in show Status 
   */
  private boolean isShowing;

  /**
   *  Whether satisfied show Conditions of 
   */
  private boolean isCanShow;

  /**
   *  Pop-up window type 
   */
  private WindowType mWindowType;

  /**
   *  Name of pop-up window 
   */
  private String mWindowName;

  private WindowWrapper(Builder builder) {
    mWindow = builder.window;
    mPriority = builder.priority;
    mWindowType = builder.windowType;
    isCanShow = builder.isCanShow;
    mWindowName = builder.windowName;
  }

  public IWindow getWindow() {
    return mWindow;
  }

  public void setWindow(IWindow window) {
    this.mWindow = window;
  }

  public int getPriority() {
    return mPriority;
  }

  public void setPriority(int priority) {
    this.mPriority = priority;
  }

  public boolean isShowing() {
    return isShowing;
  }

  public void setShowing(boolean showing) {
    isShowing = showing;
  }

  public WindowType getWindowType() {
    return mWindowType;
  }

  public void setWindowType(WindowType mWindowType) {
    this.mWindowType = mWindowType;
  }

  public boolean isCanShow() {
    return isCanShow;
  }

  public void setCanShow(boolean canShow) {
    isCanShow = canShow;
  }

  public String getWindowName() {
    return mWindowName;
  }

  public void setWindowName(String mWindowName) {
    this.mWindowName = mWindowName;
  }

  public static class Builder {

    /**
     *  Window 
     */
    private IWindow window;

    /**
     *  Priority, the higher the value, the higher the priority 
     */
    private int priority;

    /**
     *  Pop-up window type 
     */
    private WindowType windowType;

    /**
     *  Whether satisfied show Conditions of 
     */
    private boolean isCanShow;

    /**
     *  Name of pop-up window 
     */
    private String windowName;

    public Builder window(IWindow window) {
      this.window = window;
      return this;
    }

    public Builder priority(int priority) {
      this.priority = priority;
      return this;
    }

    public Builder windowType(WindowType type) {
      this.windowType = type;
      return this;
    }

    public Builder setCanShow(boolean canShow) {
      isCanShow = canShow;
      return this;
    }

    public String getWindowName() {
      return windowName;
    }

    public Builder setWindowName(String windowName) {
      this.windowName = windowName;
      return this;
    }

    public WindowWrapper build() {
      return new WindowWrapper(this);
    }
  }
}

Finally, the logic of adding, displaying and closing pop-up windows is organized and managed by WindowTaskManager class de-unification 1.


public class WindowTaskManager {
  private List<WindowWrapper> mWindows;


  private static WindowTaskManager mDefaultInstance;


  private WindowTaskManager() {
  }


  /**
   *  Get pop-up manager 
   */
  public static WindowTaskManager getInstance() {
    if (mDefaultInstance == null) {
      synchronized (WindowTaskManager.class) {
        if (mDefaultInstance == null) {
          mDefaultInstance = new WindowTaskManager();
        }
      }
    }
    return mDefaultInstance;
  }


  /**
   *  Add a pop-up window 
   *
   * @param windowWrapper  Pop-up window to be displayed 
   */
  public synchronized void addWindow(Activity activity, WindowWrapper windowWrapper) {
    if (windowWrapper != null) {
      if (mWindows == null) {
        mWindows = new ArrayList<>();
      }


      if (windowWrapper.getWindow() != null) {
        windowWrapper.getWindow().setOnWindowShowListener(new OnWindowShowListener() {
          @Override
          public void onShow() {
            windowWrapper.setShowing(true);
          }
        });


        windowWrapper.getWindow().setOnWindowDismissListener(new OnWindowDismissListener() {
          @Override
          public void onDismiss() {
            windowWrapper.setShowing(false);
            mWindows.remove(windowWrapper);
            showNext(activity);
          }
        });
      }


      mWindows.add(windowWrapper);
    }
  }


  /**
   *  The pop-up window meets the display conditions 
   *
   * @param priority
   */
  public synchronized void enableWindow(Activity activity, int priority, IWindow window) {
    WindowWrapper windowWrapper = getTargetWindow(priority);
    if (windowWrapper != null) {


      if (windowWrapper.getWindow() == null) {
        window.setOnWindowShowListener(new OnWindowShowListener() {
          @Override
          public void onShow() {
            windowWrapper.setShowing(true);
          }
        });


        window.setOnWindowDismissListener(new OnWindowDismissListener() {
          @Override
          public void onDismiss() {
            windowWrapper.setShowing(false);
            mWindows.remove(windowWrapper);
            showNext(activity);
          }
        });
      }


      windowWrapper.setCanShow(true);
      windowWrapper.setWindow(window);
      show(activity, priority);
    }
  }


  /**
   *  Remove a pop-up window that does not need to be displayed 
   *
   * @param priority
   */
  public synchronized void disableWindow(int priority) {
    WindowWrapper windowWrapper = getTargetWindow(priority);
    if (windowWrapper != null && windowWrapper.getWindow() != null) {
      if (mWindows != null) {
        mWindows.remove(windowWrapper);
      }
    }
  }


  /**
   *  Display pop-up window 
   *  From the highest priority Window Start displaying 
   */
  public synchronized void show(Activity activity) {
    WindowWrapper windowWrapper = getMaxPriorityWindow();
    if (windowWrapper != null && windowWrapper.isCanShow()) {
      IWindow window = windowWrapper.getWindow();
      if (window != null) {
        window.show(activity);
      }
    }
  }


  /**
   *  Displays the specified pop-up window 
   *
   * @param priorities
   */
  public synchronized void show(Activity activity, int priorities) {
    WindowWrapper windowWrapper = getTargetWindow(priorities);
    if (windowWrapper != null && windowWrapper.getWindow() != null) {
      WindowWrapper topShowWindow = getShowingWindow();
      if (topShowWindow == null) {
        int priority = windowWrapper.getPriority();
        WindowWrapper maxPriorityWindow = getMaxPriorityWindow();
        if (maxPriorityWindow != null && windowWrapper.isCanShow() && priority >= maxPriorityWindow.getPriority()) {
          if (windowWrapper.getWindow() != null) {
            windowWrapper.getWindow().show(activity);
          }
        }
      }
    }
  }


  /**
   *  Clear pop-up manager 
   */
  public synchronized void clear() {
    if (mWindows != null) {
      for (int i = 0, size = mWindows.size(); i < size; i++) {
        if (mWindows.get(i) != null) {
          IWindow window = mWindows.get(i).getWindow();
          if (window != null) {
            window.dismiss();
          }
        }
      }
      mWindows.clear();
    }
    WindowHelper.getInstance().onDestroy();
  }


  /**
   *  Clear pop-up manager 
   *
   * @param dismiss  Whether at the same time dismiss Drop the pop-up window maintained by the pop-up window manager 
   */
  public synchronized void clear(boolean dismiss) {
    if (mWindows != null) {
      if (dismiss) {
        for (int i = 0, size = mWindows.size(); i < size; i++) {
          if (mWindows.get(i) != null) {
            IWindow window = mWindows.get(i).getWindow();
            if (window != null) {
              window.dismiss();
            }
          }
        }
      }
      mWindows.clear();
    }
    WindowHelper.getInstance().onDestroy();
  }


  /**
   *  On display 1 The one with the highest priority Window
   */
  private synchronized void showNext(Activity activity) {
    WindowWrapper windowWrapper = getMaxPriorityWindow();
    if (windowWrapper != null && windowWrapper.isCanShow()) {
      if (windowWrapper.getWindow() != null) {
        windowWrapper.getWindow().show(activity);
      }
    }
  }


  /**
   *  Gets the highest priority in the current stack Window (If the priority is the same, return the pop-up window added later) 
   */
  private synchronized WindowWrapper getMaxPriorityWindow() {
    if (mWindows != null) {
      int maxPriority = -1;
      int position = -1;
      for (int i = 0, size = mWindows.size(); i < size; i++) {
        WindowWrapper windowWrapper = mWindows.get(i);
        if (i == 0) {
          position = 0;
          maxPriority = windowWrapper.getPriority();
        } else {
          if (windowWrapper.getPriority() >= maxPriority) {
            position = i;
            maxPriority = windowWrapper.getPriority();
          }
        }
      }
      if (position != -1) {
        return mWindows.get(position);
      } else {
        return null;
      }
    }
    return null;
  }


  private synchronized WindowWrapper getTargetWindow(int priority) {
    if (mWindows != null) {
      for (int i = 0, size = mWindows.size(); i < size; i++) {
        WindowWrapper windowWrapper = mWindows.get(i);
        if (windowWrapper != null && windowWrapper.getPriority() == priority) {
          return windowWrapper;
        }
      }
    }
    return null;
  }


  /**
   *  Gets the current show Pop-up window of status 
   */
  private synchronized WindowWrapper getShowingWindow() {
    if (mWindows != null) {
      for (int i = 0, size = mWindows.size(); i < size; i++) {
        WindowWrapper windowWrapper = mWindows.get(i);
        if (windowWrapper != null && windowWrapper.getWindow() != null && windowWrapper.isShowing()) {
          return windowWrapper;
        }
      }
    }
    return null;
  }

}

The WindowTaskManager class has three main methods:

addWindow(Activity activity, WindowWrapper windowWrapper) enableWindow(Activity activity, int priority, IWindow window) disableWindow(int priority)

Dialog Box 1 that needs to be displayed sequentially is added using the addWindow method, which is called before a network request is made. The function is to tell WindowTaskManager1 how many pop-up windows need to be displayed in sequence. When the network request returns, if you need to display the pop-up window, call the enableWindow method to display it, and if you don't need to display the pop-up window, call the disableWindow method to remove the pop-up window from the display queue.

The above is the main logic of displaying pop-up windows in sequence. If you use it, the form will inherit IWindow first and realize relevant methods. Then you can operate the WindowTaskManager class. See the source code for specific usage.

Project address: github. com/Geekince/Pr …

Easter eggs:

When DialogFragment needs to be displayed in DialogFragment, it is better not to start the display directly in DialogFragment, but in the disappearance callback of DialogFragment. Because getChildFragmentManager may fail when the current DialogFragment disappears, getFragmentManager should be used on the outer layer.

The above is how Android realizes pop-up sequence & Priority control details, more about Android to achieve pop-up sequence and priority control information please pay attention to this site other related articles!


Related articles: