2013-08-13 6 views
1

나는이 link둥근 이미지 뷰 스케일 유형

지금 내가이 원하는, 내가이 compenent에서 이미지 스케일 유형을 설정하려면 사용 둥근 이미지 뷰 구성 요소를 사용했다. 나는 센터, centercrop, fitxy 등등을 시도했다. 그러나 이미지는 자르거나 크기 유형에 따라 설정하지 않는다.

어떻게하는지 알려주세요.

답변

0

코드는 this link 일 가능성이 있습니까?

내가 아는 한 메모리 사용량면에서 훨씬 좋습니다.

public class RoundedDrawable extends Drawable { 

    public static final String TAG = "RoundedDrawable"; 
    public static final int DEFAULT_BORDER_COLOR = Color.BLACK; 

    private final RectF mBounds = new RectF(); 
    private final RectF mDrawableRect = new RectF(); 
    private final RectF mBitmapRect = new RectF(); 
    private final BitmapShader mBitmapShader; 
    private final Paint mBitmapPaint; 
    private final int mBitmapWidth; 
    private final int mBitmapHeight; 
    private final RectF mBorderRect = new RectF(); 
    private final Paint mBorderPaint; 
    private final Matrix mShaderMatrix = new Matrix(); 

    private float mCornerRadius = 0; 
    private boolean mOval = false; 
    private float mBorderWidth = 0; 
    private ColorStateList mBorderColor = ColorStateList.valueOf(DEFAULT_BORDER_COLOR); 
    private ScaleType mScaleType = ScaleType.FIT_XY; 

    public RoundedDrawable(final Bitmap bitmap) { 

     mBitmapWidth = bitmap.getWidth(); 
     mBitmapHeight = bitmap.getHeight(); 
     mBitmapRect.set(0, 0, mBitmapWidth, mBitmapHeight); 

     mBitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); 
     mBitmapShader.setLocalMatrix(mShaderMatrix); 

     mBitmapPaint = new Paint(); 
     mBitmapPaint.setStyle(Paint.Style.FILL); 
     mBitmapPaint.setAntiAlias(true); 
     mBitmapPaint.setShader(mBitmapShader); 

     mBorderPaint = new Paint(); 
     mBorderPaint.setStyle(Paint.Style.STROKE); 
     mBorderPaint.setAntiAlias(true); 
     mBorderPaint.setColor(mBorderColor.getColorForState(getState(), DEFAULT_BORDER_COLOR)); 
     mBorderPaint.setStrokeWidth(mBorderWidth); 
    } 

    public static Bitmap drawableToBitmap(final Drawable drawable) { 
     if (drawable instanceof BitmapDrawable) { 
      return ((BitmapDrawable) drawable).getBitmap(); 
     } 

     Bitmap bitmap; 
     final int width = drawable.getIntrinsicWidth(); 
     final int height = drawable.getIntrinsicHeight(); 
     if (width > 0 && height > 0) { 
      bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888); 
      final Canvas canvas = new Canvas(bitmap); 
      drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); 
      drawable.draw(canvas); 
     } else { 
      bitmap = null; 
     } 

     return bitmap; 
    } 

    public static Drawable fromDrawable(final Drawable drawable) { 
     if (drawable != null) { 
      if (drawable instanceof RoundedDrawable) { 
       // just return if it's already a RoundedDrawable 
       return drawable; 
      } else if (drawable instanceof ColorDrawable) { 
       // FIXME we don't support ColorDrawables yet 
       return drawable; 
      } else if (drawable instanceof LayerDrawable) { 
       final LayerDrawable ld = (LayerDrawable) drawable; 
       final int num = ld.getNumberOfLayers(); 

       // loop through layers to and change to RoundedDrawables if possible 
       for (int i = 0; i < num; i++) { 
        final Drawable d = ld.getDrawable(i); 
        ld.setDrawableByLayerId(ld.getId(i), fromDrawable(d)); 
       } 
       return ld; 
      } 

      // try to get a bitmap from the drawable and 
      final Bitmap bm = drawableToBitmap(drawable); 
      if (bm != null) { 
       return new RoundedDrawable(bm); 
      } else { 
       Log.w(TAG, "Failed to create bitmap from drawable!"); 
      } 
     } 
     return drawable; 
    } 

    @Override 
    public boolean isStateful() { 
     return mBorderColor.isStateful(); 
    } 

    @Override 
    protected boolean onStateChange(final int[] state) { 
     final int newColor = mBorderColor.getColorForState(state, 0); 
     if (mBorderPaint.getColor() != newColor) { 
      mBorderPaint.setColor(newColor); 
      return true; 
     } else { 
      return super.onStateChange(state); 
     } 
    } 

    private void updateShaderMatrix() { 
     mBorderRect.set(mBounds); 
     mDrawableRect.set(mBorderWidth, mBorderWidth, mBorderRect.width() - mBorderWidth, mBorderRect.height() 
       - mBorderWidth); 

     float scale; 
     float dx; 
     float dy; 

     switch (mScaleType) { 
     case CENTER: 
      mBorderRect.set(mBounds); 
      mDrawableRect.set(mBorderWidth, mBorderWidth, mBorderRect.width() - mBorderWidth, mBorderRect.height() 
        - mBorderWidth); 

      mShaderMatrix.set(null); 
      mShaderMatrix.setTranslate((int) ((mDrawableRect.width() - mBitmapWidth) * 0.5f + 0.5f), 
        (int) ((mDrawableRect.height() - mBitmapHeight) * 0.5f + 0.5f)); 
      break; 
     case CENTER_CROP: 
      mBorderRect.set(mBounds); 
      mDrawableRect.set(mBorderWidth, mBorderWidth, mBorderRect.width() - mBorderWidth, mBorderRect.height() 
        - mBorderWidth); 

      mShaderMatrix.set(null); 

      dx = 0; 
      dy = 0; 

      if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) { 
       scale = mDrawableRect.height()/mBitmapHeight; 
       dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f; 
      } else { 
       scale = mDrawableRect.width()/mBitmapWidth; 
       dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f; 
      } 

      mShaderMatrix.setScale(scale, scale); 
      mShaderMatrix.postTranslate((int) (dx + 0.5f) + mBorderWidth, (int) (dy + 0.5f) + mBorderWidth); 
      break; 
     case CENTER_INSIDE: 
      mShaderMatrix.set(null); 

      if (mBitmapWidth <= mBounds.width() && mBitmapHeight <= mBounds.height()) { 
       scale = 1.0f; 
      } else { 
       scale = Math.min(mBounds.width()/mBitmapWidth, mBounds.height()/mBitmapHeight); 
      } 

      dx = (int) ((mBounds.width() - mBitmapWidth * scale) * 0.5f + 0.5f); 
      dy = (int) ((mBounds.height() - mBitmapHeight * scale) * 0.5f + 0.5f); 

      mShaderMatrix.setScale(scale, scale); 
      mShaderMatrix.postTranslate(dx, dy); 

      mBorderRect.set(mBitmapRect); 
      mShaderMatrix.mapRect(mBorderRect); 
      mDrawableRect.set(mBorderRect.left + mBorderWidth, mBorderRect.top + mBorderWidth, mBorderRect.right 
        - mBorderWidth, mBorderRect.bottom - mBorderWidth); 
      mShaderMatrix.setRectToRect(mBitmapRect, mDrawableRect, Matrix.ScaleToFit.FILL); 
      break; 
     case FIT_CENTER: 
      mBorderRect.set(mBitmapRect); 
      mShaderMatrix.setRectToRect(mBitmapRect, mBounds, Matrix.ScaleToFit.CENTER); 
      mShaderMatrix.mapRect(mBorderRect); 
      mDrawableRect.set(mBorderRect.left + mBorderWidth, mBorderRect.top + mBorderWidth, mBorderRect.right 
        - mBorderWidth, mBorderRect.bottom - mBorderWidth); 
      mShaderMatrix.setRectToRect(mBitmapRect, mDrawableRect, Matrix.ScaleToFit.FILL); 
      break; 
     case FIT_END: 
      mBorderRect.set(mBitmapRect); 
      mShaderMatrix.setRectToRect(mBitmapRect, mBounds, Matrix.ScaleToFit.END); 
      mShaderMatrix.mapRect(mBorderRect); 
      mDrawableRect.set(mBorderRect.left + mBorderWidth, mBorderRect.top + mBorderWidth, mBorderRect.right 
        - mBorderWidth, mBorderRect.bottom - mBorderWidth); 
      mShaderMatrix.setRectToRect(mBitmapRect, mDrawableRect, Matrix.ScaleToFit.FILL); 
      break; 
     case FIT_START: 
      mBorderRect.set(mBitmapRect); 
      mShaderMatrix.setRectToRect(mBitmapRect, mBounds, Matrix.ScaleToFit.START); 
      mShaderMatrix.mapRect(mBorderRect); 
      mDrawableRect.set(mBorderRect.left + mBorderWidth, mBorderRect.top + mBorderWidth, mBorderRect.right 
        - mBorderWidth, mBorderRect.bottom - mBorderWidth); 
      mShaderMatrix.setRectToRect(mBitmapRect, mDrawableRect, Matrix.ScaleToFit.FILL); 
      break; 
     case FIT_XY: 
     default: 
      mBorderRect.set(mBounds); 
      mDrawableRect.set(0 + mBorderWidth, 0 + mBorderWidth, mBorderRect.width() - mBorderWidth, 
        mBorderRect.height() - mBorderWidth); 
      mShaderMatrix.set(null); 
      mShaderMatrix.setRectToRect(mBitmapRect, mDrawableRect, Matrix.ScaleToFit.FILL); 
      break; 
     } 

     mBorderRect.inset(mBorderWidth/2, mBorderWidth/2); 

     mBitmapShader.setLocalMatrix(mShaderMatrix); 
    } 

    @Override 
    protected void onBoundsChange(final Rect bounds) { 
     super.onBoundsChange(bounds); 

     mBounds.set(bounds); 

     updateShaderMatrix(); 
    } 

    @Override 
    public void draw(final Canvas canvas) { 

     if (mOval) { 
      if (mBorderWidth > 0) { 
       canvas.drawOval(mBorderRect, mBorderPaint); 
       canvas.drawOval(mDrawableRect, mBitmapPaint); 
      } else { 
       canvas.drawOval(mDrawableRect, mBitmapPaint); 
      } 
     } else { 
      if (mBorderWidth > 0) { 
       canvas.drawRoundRect(mBorderRect, mCornerRadius, mCornerRadius, mBorderPaint); 
       canvas.drawRoundRect(mDrawableRect, Math.max(mCornerRadius - mBorderWidth, 0), 
         Math.max(mCornerRadius - mBorderWidth, 0), mBitmapPaint); 
      } else { 
       canvas.drawRoundRect(mDrawableRect, mCornerRadius, mCornerRadius, mBitmapPaint); 
      } 
     } 
    } 

    @Override 
    public int getOpacity() { 
     return PixelFormat.TRANSLUCENT; 
    } 

    @Override 
    public void setAlpha(final int alpha) { 
     mBitmapPaint.setAlpha(alpha); 
     invalidateSelf(); 
    } 

    @Override 
    public void setColorFilter(final ColorFilter cf) { 
     mBitmapPaint.setColorFilter(cf); 
     invalidateSelf(); 
    } 

    @Override 
    public int getIntrinsicWidth() { 
     return mBitmapWidth; 
    } 

    @Override 
    public int getIntrinsicHeight() { 
     return mBitmapHeight; 
    } 

    public float getCornerRadius() { 
     return mCornerRadius; 
    } 

    public RoundedDrawable setCornerRadius(final float radius) { 
     mCornerRadius = radius; 
     return this; 
    } 

    public float getBorderWidth() { 
     return mBorderWidth; 
    } 

    public RoundedDrawable setBorderWidth(final int width) { 
     mBorderWidth = width; 
     mBorderPaint.setStrokeWidth(mBorderWidth); 
     return this; 
    } 

    public int getBorderColor() { 
     return mBorderColor.getDefaultColor(); 
    } 

    public RoundedDrawable setBorderColor(final int color) { 
     return setBorderColors(ColorStateList.valueOf(color)); 
    } 

    public ColorStateList getBorderColors() { 
     return mBorderColor; 
    } 

    public RoundedDrawable setBorderColors(final ColorStateList colors) { 
     mBorderColor = colors != null ? colors : ColorStateList.valueOf(0); 
     mBorderPaint.setColor(mBorderColor.getColorForState(getState(), DEFAULT_BORDER_COLOR)); 
     return this; 
    } 

    public boolean isOval() { 
     return mOval; 
    } 

    public RoundedDrawable setOval(final boolean oval) { 
     mOval = oval; 
     return this; 
    } 

    public ScaleType getScaleType() { 
     return mScaleType; 
    } 

    public RoundedDrawable setScaleType(ScaleType scaleType) { 
     if (scaleType == null) { 
      scaleType = ScaleType.FIT_XY; 
     } 
     if (mScaleType != scaleType) { 
      mScaleType = scaleType; 
      updateShaderMatrix(); 
     } 
     return this; 
    } 
} 

attr.xml

,536 RoundedDrawable.java

RoundedImageView.java

public class RoundedImageView extends ImageView { 
    // based on https://github.com/makeramen/RoundedImageView 
    public static final String TAG = "RoundedImageView"; 

    public static final int DEFAULT_RADIUS = 0; 
    public static final int DEFAULT_BORDER = 0; 
    public static final int DEFAULT_BORDER_COLOR = Color.BLACK; 

    private int mCornerRadius; 
    private int mBorderWidth; 
    private int mBorderColor; 

    private boolean roundBackground; 

    private Drawable mDrawable; 
    private Drawable mBackgroundDrawable; 

    private ScaleType mScaleType; 

    private static final ScaleType[] sScaleTypeArray = { ScaleType.MATRIX, ScaleType.FIT_XY, ScaleType.FIT_START, 
      ScaleType.FIT_CENTER, ScaleType.FIT_END, ScaleType.CENTER, ScaleType.CENTER_CROP, ScaleType.CENTER_INSIDE }; 

    public RoundedImageView(final Context context) { 
     super(context); 
     mCornerRadius = DEFAULT_RADIUS; 
     mBorderWidth = DEFAULT_BORDER; 
     mBorderColor = DEFAULT_BORDER_COLOR; 
    } 

    public RoundedImageView(final Context context, final AttributeSet attrs) { 
     this(context, attrs, 0); 
    } 

    public RoundedImageView(final Context context, final AttributeSet attrs, final int defStyle) { 
     super(context, attrs, defStyle); 

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

     final int index = a.getInt(R.styleable.RoundedImageView_android_scaleType, -1); 
     if (index >= 0) { 
      setScaleType(sScaleTypeArray[index]); 
     } 

     mCornerRadius = a.getDimensionPixelSize(R.styleable.RoundedImageView_corner_radius, -1); 
     mBorderWidth = a.getDimensionPixelSize(R.styleable.RoundedImageView_border_width, -1); 

     // don't allow negative values for radius and border 
     if (mCornerRadius < 0) { 
      mCornerRadius = DEFAULT_RADIUS; 
     } 
     if (mBorderWidth < 0) { 
      mBorderWidth = DEFAULT_BORDER; 
     } 

     mBorderColor = a.getColor(R.styleable.RoundedImageView_border_color, DEFAULT_BORDER_COLOR); 

     roundBackground = a.getBoolean(R.styleable.RoundedImageView_round_background, false); 

     a.recycle(); 
    } 

    /** 
    * Controls how the image should be resized or moved to match the size of this ImageView. 
    * 
    * @param scaleType 
    *   The desired scaling mode. 
    * 
    * @attr ref android.R.styleable#ImageView_scaleType 
    */ 
    @Override 
    public void setScaleType(final ScaleType scaleType) { 
     if (scaleType == null) { 
      throw new NullPointerException(); 
     } 

     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; 
      } 

      if (mDrawable instanceof RoundedDrawable && ((RoundedDrawable) mDrawable).getScaleType() != scaleType) { 
       ((RoundedDrawable) mDrawable).setScaleType(scaleType); 
      } 

      if (mBackgroundDrawable instanceof RoundedDrawable 
        && ((RoundedDrawable) mBackgroundDrawable).getScaleType() != scaleType) { 
       ((RoundedDrawable) mBackgroundDrawable).setScaleType(scaleType); 
      } 
      setWillNotCacheDrawing(true); 
      requestLayout(); 
      invalidate(); 
     } 
    } 

    /** 
    * Return the current scale type in use by this ImageView. 
    * 
    * @see ImageView.ScaleType 
    * 
    * @attr ref android.R.styleable#ImageView_scaleType 
    */ 
    @Override 
    public ScaleType getScaleType() { 
     return mScaleType; 
    } 

    @Override 
    public void setImageDrawable(final Drawable drawable) { 
     if (drawable != null) { 
      mDrawable = RoundedDrawable.fromDrawable(drawable, mCornerRadius, mBorderWidth, mBorderColor); 
      ((RoundedDrawable) mDrawable).setScaleType(mScaleType); 
      ((RoundedDrawable) mDrawable).setCornerRadius(mCornerRadius); 
      ((RoundedDrawable) mDrawable).setBorderWidth(mBorderWidth); 
      ((RoundedDrawable) mDrawable).setBorderColor(mBorderColor); 
     } else { 
      mDrawable = null; 
     } 
     super.setImageDrawable(mDrawable); 
    } 

    @Override 
    public void setImageBitmap(final Bitmap bm) { 
     if (bm != null) { 
      mDrawable = new RoundedDrawable(bm, mCornerRadius, mBorderWidth, mBorderColor); 
      ((RoundedDrawable) mDrawable).setScaleType(mScaleType); 
      ((RoundedDrawable) mDrawable).setCornerRadius(mCornerRadius); 
      ((RoundedDrawable) mDrawable).setBorderWidth(mBorderWidth); 
      ((RoundedDrawable) mDrawable).setBorderColor(mBorderColor); 
     } else { 
      mDrawable = null; 
     } 
     super.setImageDrawable(mDrawable); 
    } 

    // @Override 
    // public void setBackground(final Drawable background) { 
    // setBackgroundDrawable(background); 
    // } 

    @Override 
    @Deprecated 
    public void setBackgroundDrawable(final Drawable background) { 
     if (roundBackground && background != null) { 
      mBackgroundDrawable = RoundedDrawable.fromDrawable(background, mCornerRadius, mBorderWidth, mBorderColor); 
      ((RoundedDrawable) mBackgroundDrawable).setScaleType(mScaleType); 
      ((RoundedDrawable) mBackgroundDrawable).setCornerRadius(mCornerRadius); 
      ((RoundedDrawable) mBackgroundDrawable).setBorderWidth(mBorderWidth); 
      ((RoundedDrawable) mBackgroundDrawable).setBorderColor(mBorderColor); 
     } else { 
      mBackgroundDrawable = background; 
     } 
     super.setBackgroundDrawable(mBackgroundDrawable); 
    } 

    public int getCornerRadius() { 
     return mCornerRadius; 
    } 

    public int getBorder() { 
     return mBorderWidth; 
    } 

    public int getBorderColor() { 
     return mBorderColor; 
    } 

    public void setCornerRadius(final int radius) { 
     if (mCornerRadius == radius) { 
      return; 
     } 

     this.mCornerRadius = radius; 
     if (mDrawable instanceof RoundedDrawable) { 
      ((RoundedDrawable) mDrawable).setCornerRadius(radius); 
     } 
     if (roundBackground && mBackgroundDrawable instanceof RoundedDrawable) { 
      ((RoundedDrawable) mBackgroundDrawable).setCornerRadius(radius); 
     } 
    } 

    public void setBorderWidth(final int width) { 
     if (mBorderWidth == width) { 
      return; 
     } 

     this.mBorderWidth = width; 
     if (mDrawable instanceof RoundedDrawable) { 
      ((RoundedDrawable) mDrawable).setBorderWidth(width); 
     } 
     if (roundBackground && mBackgroundDrawable instanceof RoundedDrawable) { 
      ((RoundedDrawable) mBackgroundDrawable).setBorderWidth(width); 
     } 
     invalidate(); 
    } 

    public void setBorderColor(final int color) { 
     if (mBorderColor == color) { 
      return; 
     } 

     this.mBorderColor = color; 
     if (mDrawable instanceof RoundedDrawable) { 
      ((RoundedDrawable) mDrawable).setBorderColor(color); 
     } 
     if (roundBackground && mBackgroundDrawable instanceof RoundedDrawable) { 
      ((RoundedDrawable) mBackgroundDrawable).setBorderColor(color); 
     } 
     if (mBorderWidth > 0) { 
      invalidate(); 
     } 
    } 

    public boolean isRoundBackground() { 
     return roundBackground; 
    } 

    public void setRoundBackground(final boolean roundBackground) { 
     if (this.roundBackground == roundBackground) { 
      return; 
     } 

     this.roundBackground = roundBackground; 
     if (roundBackground) { 
      if (mBackgroundDrawable instanceof RoundedDrawable) { 
       ((RoundedDrawable) mBackgroundDrawable).setScaleType(mScaleType); 
       ((RoundedDrawable) mBackgroundDrawable).setCornerRadius(mCornerRadius); 
       ((RoundedDrawable) mBackgroundDrawable).setBorderWidth(mBorderWidth); 
       ((RoundedDrawable) mBackgroundDrawable).setBorderColor(mBorderColor); 
      } else { 
       setBackgroundDrawable(mBackgroundDrawable); 
      } 
     } else if (mBackgroundDrawable instanceof RoundedDrawable) { 
      ((RoundedDrawable) mBackgroundDrawable).setBorderWidth(0); 
      ((RoundedDrawable) mBackgroundDrawable).setCornerRadius(0); 
     } 

     invalidate(); 
    } 
} 

: 여기

코드입니다
<declare-styleable name="RoundedImageView"> 
    <attr name="corner_radius" format="dimension" /> 
    <attr name="round_background" format="boolean" /> 
    <attr name="android:scaleType" /> 
    <!-- border --> 
    <attr name="border_width" format="dimension" /> 
    <attr name="border_color" format="color" /> 
</declare-styleable>