@Override
 public void setImageBitmap(Bitmap bm) {
   mResource = 0;
   mDrawable = RoundedDrawable.fromBitmap(bm);
   updateDrawableAttrs();
   super.setImageDrawable(mDrawable);
 }
 @Override
 public void setImageDrawable(Drawable drawable) {
   mResource = 0;
   mDrawable = RoundedDrawable.fromDrawable(drawable);
   updateDrawableAttrs();
   super.setImageDrawable(mDrawable);
 }
  @Override
  public void setScaleType(ScaleType scaleType) {
    assert scaleType != null;

    if (mScaleType != scaleType) {
      mScaleType = scaleType;

      switch (scaleType) {
        case CENTER:
        case CENTER_CROP:
        case CENTER_INSIDE:
        case FIT_CENTER:
        case FIT_START:
        case FIT_END:
        case FIT_XY:
          super.setScaleType(ScaleType.FIT_XY);
          break;
        default:
          super.setScaleType(scaleType);
          break;
      }

      updateDrawableAttrs();
      updateBackgroundDrawableAttrs(false);
      invalidate();
    }
  }
 @Override
 public void setImageResource(@DrawableRes int resId) {
   if (mResource != resId) {
     mResource = resId;
     mDrawable = resolveResource();
     updateDrawableAttrs();
     super.setImageDrawable(mDrawable);
   }
 }
  public void setTileModeY(Shader.TileMode tileModeY) {
    if (this.mTileModeY == tileModeY) {
      return;
    }

    this.mTileModeY = tileModeY;
    updateDrawableAttrs();
    updateBackgroundDrawableAttrs(false);
    invalidate();
  }
  public void setBorderWidth(float width) {
    if (mBorderWidth == width) {
      return;
    }

    mBorderWidth = width;
    updateDrawableAttrs();
    updateBackgroundDrawableAttrs(false);
    invalidate();
  }
  /**
   * Set the corner radius of a specific corner in px.
   *
   * @param corner the corner to set.
   * @param radius the corner radius to set in px.
   */
  public void setCornerRadius(int corner, float radius) {
    if (mCornerRadii[corner] == radius) {
      return;
    }
    mCornerRadii[corner] = radius;

    updateDrawableAttrs();
    updateBackgroundDrawableAttrs(false);
    invalidate();
  }
  public void setBorderColor(ColorStateList colors) {
    if (mBorderColor.equals(colors)) {
      return;
    }

    mBorderColor =
        (colors != null) ? colors : ColorStateList.valueOf(RoundedDrawable.DEFAULT_BORDER_COLOR);
    updateDrawableAttrs();
    updateBackgroundDrawableAttrs(false);
    if (mBorderWidth > 0) {
      invalidate();
    }
  }
  /**
   * Set the corner radii of each corner individually. Currently only one unique nonzero value is
   * supported.
   *
   * @param topLeft radius of the top left corner in px.
   * @param topRight radius of the top right corner in px.
   * @param bottomRight radius of the bottom right corner in px.
   * @param bottomLeft radius of the bottom left corner in px.
   */
  public void setCornerRadius(float topLeft, float topRight, float bottomLeft, float bottomRight) {
    if (mCornerRadii[CORNER_TOP_LEFT] == topLeft
        && mCornerRadii[CORNER_TOP_RIGHT] == topRight
        && mCornerRadii[CORNER_BOTTOM_RIGHT] == bottomRight
        && mCornerRadii[CORNER_BOTTOM_LEFT] == bottomLeft) {
      return;
    }

    mCornerRadii[CORNER_TOP_LEFT] = topLeft;
    mCornerRadii[CORNER_TOP_RIGHT] = topRight;
    mCornerRadii[CORNER_BOTTOM_LEFT] = bottomLeft;
    mCornerRadii[CORNER_BOTTOM_RIGHT] = bottomRight;

    updateDrawableAttrs();
    updateBackgroundDrawableAttrs(false);
    invalidate();
  }
  public RoundedImageView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);

    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundedImageView, defStyle, 0);

    int index = a.getInt(R.styleable.RoundedImageView_android_scaleType, -1);
    if (index >= 0) {
      setScaleType(SCALE_TYPES[index]);
    } else {
      // default scaletype to FIT_CENTER
      setScaleType(ScaleType.FIT_CENTER);
    }

    float cornerRadiusOverride =
        a.getDimensionPixelSize(R.styleable.RoundedImageView_riv_corner_radius, -1);

    mCornerRadii[CORNER_TOP_LEFT] =
        a.getDimensionPixelSize(R.styleable.RoundedImageView_riv_corner_radius_top_left, -1);
    mCornerRadii[CORNER_TOP_RIGHT] =
        a.getDimensionPixelSize(R.styleable.RoundedImageView_riv_corner_radius_top_right, -1);
    mCornerRadii[CORNER_BOTTOM_RIGHT] =
        a.getDimensionPixelSize(R.styleable.RoundedImageView_riv_corner_radius_bottom_right, -1);
    mCornerRadii[CORNER_BOTTOM_LEFT] =
        a.getDimensionPixelSize(R.styleable.RoundedImageView_riv_corner_radius_bottom_left, -1);

    boolean any = false;
    for (int i = 0, len = mCornerRadii.length; i < len; i++) {
      if (mCornerRadii[i] < 0) {
        mCornerRadii[i] = 0f;
      } else {
        any = true;
      }
    }

    if (!any) {
      if (cornerRadiusOverride < 0) {
        cornerRadiusOverride = DEFAULT_RADIUS;
      }
      for (int i = 0, len = mCornerRadii.length; i < len; i++) {
        mCornerRadii[i] = cornerRadiusOverride;
      }
    }

    mBorderWidth = a.getDimensionPixelSize(R.styleable.RoundedImageView_riv_border_width, -1);
    if (mBorderWidth < 0) {
      mBorderWidth = DEFAULT_BORDER_WIDTH;
    }

    mBorderColor = a.getColorStateList(R.styleable.RoundedImageView_riv_border_color);
    if (mBorderColor == null) {
      mBorderColor = ColorStateList.valueOf(RoundedDrawable.DEFAULT_BORDER_COLOR);
    }

    mMutateBackground = a.getBoolean(R.styleable.RoundedImageView_riv_mutate_background, false);
    mIsOval = a.getBoolean(R.styleable.RoundedImageView_riv_oval, false);

    final int tileMode = a.getInt(R.styleable.RoundedImageView_riv_tile_mode, TILE_MODE_UNDEFINED);
    if (tileMode != TILE_MODE_UNDEFINED) {
      setTileModeX(parseTileMode(tileMode));
      setTileModeY(parseTileMode(tileMode));
    }

    final int tileModeX =
        a.getInt(R.styleable.RoundedImageView_riv_tile_mode_x, TILE_MODE_UNDEFINED);
    if (tileModeX != TILE_MODE_UNDEFINED) {
      setTileModeX(parseTileMode(tileModeX));
    }

    final int tileModeY =
        a.getInt(R.styleable.RoundedImageView_riv_tile_mode_y, TILE_MODE_UNDEFINED);
    if (tileModeY != TILE_MODE_UNDEFINED) {
      setTileModeY(parseTileMode(tileModeY));
    }

    updateDrawableAttrs();
    updateBackgroundDrawableAttrs(true);

    a.recycle();
  }
 public void setOval(boolean oval) {
   mIsOval = oval;
   updateDrawableAttrs();
   updateBackgroundDrawableAttrs(false);
   invalidate();
 }