void addMarker(int index, PageMarkerResources marker, boolean allowAnimations) {
    index = Math.max(0, Math.min(index, mMarkers.size()));

    PageIndicatorMarker m =
        (PageIndicatorMarker) mLayoutInflater.inflate(R.layout.page_indicator_marker, this, false);
    m.setMarkerDrawables(marker.activeId, marker.inactiveId);

    mMarkers.add(index, m);
    offsetWindowCenterTo(mActiveMarkerIndex, allowAnimations);
  }
  void offsetWindowCenterTo(int activeIndex, boolean allowAnimations) {
    if (activeIndex < 0) {
      new Throwable().printStackTrace();
    }
    int windowSize = Math.min(mMarkers.size(), mMaxWindowSize);
    int hWindowSize = (int) windowSize / 2;
    float hfWindowSize = windowSize / 2f;
    int windowStart = Math.max(0, activeIndex - hWindowSize);
    int windowEnd = Math.min(mMarkers.size(), windowStart + mMaxWindowSize);
    windowStart = windowEnd - Math.min(mMarkers.size(), windowSize);
    int windowMid = windowStart + (windowEnd - windowStart) / 2;
    boolean windowAtStart = (windowStart == 0);
    boolean windowAtEnd = (windowEnd == mMarkers.size());
    boolean windowMoved = (mWindowRange[0] != windowStart) || (mWindowRange[1] != windowEnd);

    if (!allowAnimations) {
      disableLayoutTransitions();
    }

    // Remove all the previous children that are no longer in the window
    for (int i = getChildCount() - 1; i >= 0; --i) {
      PageIndicatorMarker marker = (PageIndicatorMarker) getChildAt(i);
      int markerIndex = mMarkers.indexOf(marker);
      if (markerIndex < windowStart || markerIndex >= windowEnd) {
        removeView(marker);
      }
    }

    // Add all the new children that belong in the window
    for (int i = 0; i < mMarkers.size(); ++i) {
      PageIndicatorMarker marker = (PageIndicatorMarker) mMarkers.get(i);
      if (windowStart <= i && i < windowEnd) {
        if (indexOfChild(marker) < 0) {
          addView(marker, i - windowStart);
        }
        if (i == activeIndex) {
          marker.activate(windowMoved);
        } else {
          marker.inactivate(windowMoved);
        }
      } else {
        marker.inactivate(true);
      }

      if (MODULATE_ALPHA_ENABLED) {
        // Update the marker's alpha
        float alpha = 1f;
        if (mMarkers.size() > windowSize) {
          if ((windowAtStart && i > hWindowSize)
              || (windowAtEnd && i < (mMarkers.size() - hWindowSize))
              || (!windowAtStart && !windowAtEnd)) {
            alpha = 1f - Math.abs((i - windowMid) / hfWindowSize);
          }
        }
        marker.animate().alpha(alpha).setDuration(500).start();
      }
    }

    if (!allowAnimations) {
      enableLayoutTransitions();
    }

    mWindowRange[0] = windowStart;
    mWindowRange[1] = windowEnd;
  }
 void updateMarker(int index, PageMarkerResources marker) {
   PageIndicatorMarker m = mMarkers.get(index);
   m.setMarkerDrawables(marker.activeId, marker.inactiveId);
 }