欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android 如何實(shí)現(xiàn)彈窗順序&優(yōu)先級(jí)控制

 更新時(shí)間:2021年03月31日 08:59:28   作者:金宇世界  
這篇文章主要介紹了Android 如何實(shí)現(xiàn)彈窗順序&優(yōu)先級(jí)控制,幫助大家更好的理解和學(xué)習(xí)使用Android,感興趣的朋友可以了解下

一般在項(xiàng)目首頁(yè)中,往往會(huì)有多個(gè)對(duì)話框需要彈出,比如活動(dòng)彈窗、更新彈窗、評(píng)分彈窗等等,而且這些彈窗是有優(yōu)先級(jí)順序的。這些彈窗一般是通過(guò)接口請(qǐng)求后返回結(jié)果再顯示的,如果只有幾個(gè)彈窗還好處理,業(yè)務(wù)邏輯上判斷一下先后顯示就可以。如果有十幾個(gè)或者更多,那么處理起來(lái)將非常麻煩,而且容易出現(xiàn)問(wèn)題。

所以封裝一個(gè)可以按照優(yōu)先級(jí)順序顯示的彈窗功能就非常有必要,首先功能需求如下:

  • 按優(yōu)先級(jí)順序阻塞式顯示各種類(lèi)型彈窗,默認(rèn)從最高優(yōu)先級(jí)開(kāi)始顯示
  • 只有上一個(gè)高優(yōu)先級(jí)彈窗顯示完或者取消顯示,下一個(gè)低優(yōu)先級(jí)彈窗才可以顯示
  • 指定顯示某一個(gè)彈窗的前提是沒(méi)有更高優(yōu)先級(jí)的彈窗需要顯示
  • 在顯示一個(gè)彈窗之前需要判斷是否能夠或者需要顯示
  • 根據(jù)優(yōu)先級(jí)去查找指定的彈窗,優(yōu)先級(jí)相當(dāng)于唯一ID
  • 彈窗包括多種類(lèi)型,Dialog、PopupWindow、Activity等等

接著開(kāi)始編碼去實(shí)現(xiàn)功能,先定一個(gè)枚舉類(lèi),羅列出支持的彈窗類(lèi)型,包括Dialog、PopupWindow、Activity等等。

public enum WindowType {

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

}

然后定義彈窗接口IWindow,它定義了彈窗的基本功能。

/**
* 窗口約定規(guī)則
*/
public interface IWindow {

  /**
   * 彈窗展示
   */
  void show(Activity activity);

  /**
   * 彈窗關(guān)閉
   */
  void dismiss();

  /**
   * 設(shè)置窗口關(guān)閉監(jiān)聽(tīng)
   */
  void setOnWindowDismissListener(OnWindowDismissListener listener);

  /**
   * 設(shè)置窗口展示監(jiān)聽(tīng)
   */
  void setOnWindowShowListener(OnWindowShowListener listener);

}

以及彈窗顯示和關(guān)閉的監(jiān)聽(tīng)接口,

/**
* 窗口關(guān)閉監(jiān)聽(tīng)
*/
public interface OnWindowDismissListener {

  /**
   *
   */
  void onDismiss();

}

/**
* 窗口展示監(jiān)聽(tīng)
*/
public interface OnWindowShowListener {

  void onShow();

}

接下來(lái)定義個(gè)包裹類(lèi)WindowWrapper去封裝彈窗相關(guān)的屬性和狀態(tài),包括彈窗、優(yōu)先級(jí)、能否顯示、窗體類(lèi)型等等,在處理彈窗顯示邏輯時(shí)將會(huì)用到。

/**
* 窗口參數(shù)類(lèi)
*/
public class WindowWrapper {

  /**
   * 窗口
   */
  private IWindow mWindow;

  /**
   * 優(yōu)先級(jí),值越大優(yōu)先級(jí)越高
   */
  private int mPriority;

  /**
   * 當(dāng)前是否處于show狀態(tài)
   */
  private boolean isShowing;

  /**
   * 是否滿(mǎn)足show的條件
   */
  private boolean isCanShow;

  /**
   * 彈窗類(lèi)型
   */
  private WindowType mWindowType;

  /**
   * 彈窗名稱(chēng)
   */
  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 {

    /**
     * 窗口
     */
    private IWindow window;

    /**
     * 優(yōu)先級(jí),值越大優(yōu)先級(jí)越高
     */
    private int priority;

    /**
     * 彈窗類(lèi)型
     */
    private WindowType windowType;

    /**
     * 是否滿(mǎn)足show的條件
     */
    private boolean isCanShow;

    /**
     * 彈窗名稱(chēng)
     */
    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);
    }
  }
}

最后通過(guò)WindowTaskManager類(lèi)去統(tǒng)一組織管理彈窗的添加、顯示、關(guān)閉等邏輯,

public class WindowTaskManager {
  private List<WindowWrapper> mWindows;


  private static WindowTaskManager mDefaultInstance;


  private WindowTaskManager() {
  }


  /**
   * 獲取彈窗管理者
   */
  public static WindowTaskManager getInstance() {
    if (mDefaultInstance == null) {
      synchronized (WindowTaskManager.class) {
        if (mDefaultInstance == null) {
          mDefaultInstance = new WindowTaskManager();
        }
      }
    }
    return mDefaultInstance;
  }


  /**
   * 添加彈窗
   *
   * @param windowWrapper 待顯示的彈窗
   */
  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);
    }
  }


  /**
   * 彈窗滿(mǎn)足展示條件
   *
   * @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);
    }
  }


  /**
   * 移除不需要顯示彈窗
   *
   * @param priority
   */
  public synchronized void disableWindow(int priority) {
    WindowWrapper windowWrapper = getTargetWindow(priority);
    if (windowWrapper != null && windowWrapper.getWindow() != null) {
      if (mWindows != null) {
        mWindows.remove(windowWrapper);
      }
    }
  }


  /**
   * 展示彈窗
   * 從優(yōu)先級(jí)最高的Window開(kāi)始顯示
   */
  public synchronized void show(Activity activity) {
    WindowWrapper windowWrapper = getMaxPriorityWindow();
    if (windowWrapper != null && windowWrapper.isCanShow()) {
      IWindow window = windowWrapper.getWindow();
      if (window != null) {
        window.show(activity);
      }
    }
  }


  /**
   * 顯示指定的彈窗
   *
   * @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);
          }
        }
      }
    }
  }


  /**
   * 清除彈窗管理者
   */
  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();
  }


  /**
   * 清除彈窗管理者
   *
   * @param dismiss 是否同時(shí)dismiss掉彈窗管理者維護(hù)的彈窗
   */
  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();
  }


  /**
   * 展示下一個(gè)優(yōu)先級(jí)最大的Window
   */
  private synchronized void showNext(Activity activity) {
    WindowWrapper windowWrapper = getMaxPriorityWindow();
    if (windowWrapper != null && windowWrapper.isCanShow()) {
      if (windowWrapper.getWindow() != null) {
        windowWrapper.getWindow().show(activity);
      }
    }
  }


  /**
   * 獲取當(dāng)前棧中優(yōu)先級(jí)最高的Window(優(yōu)先級(jí)相同則返回后添加的彈窗)
   */
  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;
  }


  /**
   * 獲取當(dāng)前處于show狀態(tài)的彈窗
   */
  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;
  }

}

WindowTaskManager類(lèi)有三個(gè)主要方法:

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

需要按順序顯示的對(duì)話框統(tǒng)一使用addWindow方法添加,這是還未進(jìn)行網(wǎng)絡(luò)請(qǐng)求之前就要調(diào)用的。作用是告訴WindowTaskManager一共有多少個(gè)彈窗需要按順序顯示。當(dāng)網(wǎng)絡(luò)請(qǐng)求返回之后,如果需要顯示彈窗就調(diào)用enableWindow方法去顯示,如果不需要顯示彈窗就調(diào)用disableWindow方法,將這個(gè)彈窗從顯示隊(duì)列中移除。

以上就是按順序顯示彈窗的主要邏輯,使用的話窗體先繼承IWindow,實(shí)現(xiàn)相關(guān)方法。然后通過(guò)操作WindowTaskManager類(lèi)就可以了。具體使用方法參見(jiàn)源碼。

項(xiàng)目地址:github.com/Geekince/Pr…

彩蛋:

需要在DialogFragment中顯示DialogFragment時(shí)候,最好不要直接在DialogFragment啟動(dòng)顯示,而是在DialogFragment的消失回調(diào)中啟動(dòng)顯示。因?yàn)楫?dāng)前一個(gè)DialogFragment消失的時(shí)候,getChildFragmentManager可能會(huì)失效,應(yīng)該在外層使用getFragmentManager。

以上就是Android 如何實(shí)現(xiàn)彈窗順序&優(yōu)先級(jí)控制的詳細(xì)內(nèi)容,更多關(guān)于Android 實(shí)現(xiàn)彈窗順序和優(yōu)先級(jí)控制的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論