@Override
  protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    mBackground.setBounds(0, 0, w, h);

    if (mIcon != null) {
      float half = mIconSize / 2f;
      mIcon.setBounds(
          (int) (mBackground.getCenterX() - half),
          (int) (mBackground.getCenterY() - half),
          (int) (mBackground.getCenterX() + half),
          (int) (mBackground.getCenterY() + half));
    }

    if (mPrevIcon != null) {
      float half = mIconSize / 2f;
      mPrevIcon.setBounds(
          (int) (mBackground.getCenterX() - half),
          (int) (mBackground.getCenterY() - half),
          (int) (mBackground.getCenterX() + half),
          (int) (mBackground.getCenterY() + half));
    }
  }
  /**
   * Set the drawable that is used as this button's icon.
   *
   * @param icon The drawable.
   * @param animation Indicate should show animation when switch drawable or not.
   */
  public void setIcon(Drawable icon, boolean animation) {
    if (icon == null) return;

    if (animation) {
      mSwitchIconAnimator.startAnimation(icon);
      invalidate();
    } else {
      if (mIcon != null) {
        mIcon.setCallback(null);
        unscheduleDrawable(mIcon);
      }

      mIcon = icon;
      float half = mIconSize / 2f;
      mIcon.setBounds(
          (int) (mBackground.getCenterX() - half),
          (int) (mBackground.getCenterY() - half),
          (int) (mBackground.getCenterX() + half),
          (int) (mBackground.getCenterY() + half));
      mIcon.setCallback(this);
      invalidate();
    }
  }
  private void updateParams(int x, int y, int gravity, ViewGroup.LayoutParams params) {
    int horizontalGravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK;

    switch (horizontalGravity) {
      case Gravity.LEFT:
        setLeftMargin(params, (int) (x - mBackground.getPaddingLeft()));
        break;
      case Gravity.CENTER_HORIZONTAL:
        setLeftMargin(params, (int) (x - mBackground.getCenterX()));
        break;
      case Gravity.RIGHT:
        setLeftMargin(
            params, (int) (x - mBackground.getPaddingLeft() - mBackground.getRadius() * 2));
        break;
      default:
        setLeftMargin(params, (int) (x - mBackground.getPaddingLeft()));
        break;
    }

    int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;

    switch (verticalGravity) {
      case Gravity.TOP:
        setTopMargin(params, (int) (y - mBackground.getPaddingTop()));
        break;
      case Gravity.CENTER_VERTICAL:
        setTopMargin(params, (int) (y - mBackground.getCenterY()));
        break;
      case Gravity.BOTTOM:
        setTopMargin(params, (int) (y - mBackground.getPaddingTop() - mBackground.getRadius() * 2));
        break;
      default:
        setTopMargin(params, (int) (y - mBackground.getPaddingTop()));
        break;
    }

    setLayoutParams(params);
  }