예제 #1
0
  // This callback is automatically executed on the UI thread.
  @Override
  public void onTabChanged(final Tab tab, final Tabs.TabEvents msg, final Object data) {
    switch (msg) {
      case CLOSED:
        // Remove any doorhangers for a tab when it's closed (make
        // a temporary set to avoid a ConcurrentModificationException)
        HashSet<DoorHanger> doorHangersToRemove = new HashSet<DoorHanger>();
        for (DoorHanger dh : mDoorHangers) {
          if (dh.getTabId() == tab.getId()) doorHangersToRemove.add(dh);
        }
        for (DoorHanger dh : doorHangersToRemove) {
          removeDoorHanger(dh);
        }
        break;

      case LOCATION_CHANGE:
        // Only remove doorhangers if the popup is hidden or if we're navigating to a new URL
        if (!isShowing() || !data.equals(tab.getURL())) removeTransientDoorHangers(tab.getId());

        // Update the popup if the location change was on the current tab
        if (Tabs.getInstance().isSelectedTab(tab)) updatePopup();
        break;

      case SELECTED:
        // Always update the popup when a new tab is selected. This will cover cases
        // where a different tab was closed, since we always need to select a new tab.
        updatePopup();
        break;
    }
  }
예제 #2
0
  /**
   * Gets a doorhanger.
   *
   * <p>This method must be called on the UI thread.
   */
  DoorHanger getDoorHanger(int tabId, String value) {
    for (DoorHanger dh : mDoorHangers) {
      if (dh.getTabId() == tabId && dh.getValue().equals(value)) return dh;
    }

    // If there's no doorhanger for the given tabId and value, return null
    return null;
  }
예제 #3
0
  /**
   * Removes doorhangers for a given tab.
   *
   * <p>This method must be called on the UI thread.
   */
  void removeTransientDoorHangers(int tabId) {
    // Make a temporary set to avoid a ConcurrentModificationException
    HashSet<DoorHanger> doorHangersToRemove = new HashSet<DoorHanger>();
    for (DoorHanger dh : mDoorHangers) {
      // Only remove transient doorhangers for the given tab
      if (dh.getTabId() == tabId && dh.shouldRemove(isShowing())) doorHangersToRemove.add(dh);
    }

    for (DoorHanger dh : doorHangersToRemove) {
      removeDoorHanger(dh);
    }
  }
예제 #4
0
  /**
   * Updates the popup state.
   *
   * <p>This method must be called on the UI thread.
   */
  void updatePopup() {
    // Bail if the selected tab is null, if there are no active doorhangers,
    // if we haven't inflated the layout yet (this can happen if updatePopup()
    // is called before the runnable from addDoorHanger() runs), or if the
    // doorhanger popup is temporarily disabled.
    Tab tab = Tabs.getInstance().getSelectedTab();
    if (tab == null || mDoorHangers.size() == 0 || !mInflated || mDisabled) {
      dismiss();
      return;
    }

    // Show doorhangers for the selected tab
    int tabId = tab.getId();
    boolean shouldShowPopup = false;
    for (DoorHanger dh : mDoorHangers) {
      if (dh.getTabId() == tabId) {
        dh.setVisibility(View.VISIBLE);
        shouldShowPopup = true;
      } else {
        dh.setVisibility(View.GONE);
      }
    }

    // Dismiss the popup if there are no doorhangers to show for this tab
    if (!shouldShowPopup) {
      dismiss();
      return;
    }

    showDividers();
    if (isShowing()) {
      show();
      return;
    }

    // Make the popup focusable for accessibility. This gets done here
    // so the node can be accessibility focused, but on pre-ICS devices this
    // causes crashes, so it is done after the popup is shown.
    if (Build.VERSION.SDK_INT >= 14) {
      setFocusable(true);
    }

    show();

    if (Build.VERSION.SDK_INT < 14) {
      // Make the popup focusable for keyboard accessibility.
      setFocusable(true);
    }
  }