<com.abc.widgets.CircularImageView android:id="@+id/act_chat_img_profile" android:layout_width="@dimen/_38sdp" android:layout_height="@dimen/_38sdp" android:layout_gravity="center" android:gravity="center" android:scaleType="centerCrop" android:src="@mipmap/default_profile" app:border="false" app:shadow="false"/>
package com.piitch.widgets; import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Shader; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.media.ThumbnailUtils; import android.os.Build; import android.util.AttributeSet; import android.util.Log; import android.widget.ImageView; import com.piitch.R; /** * Created by Mikhael LOPEZ on 09/10/2015. */ @SuppressLint("AppCompatCustomView") public class CircularImageView extends ImageView { // Properties private int borderWidth; private int canvasSize; private float shadowRadius = 8.0f; private int shadowColor = Color.BLACK; // Object used to draw private Bitmap image; private Drawable drawable; private Paint paint; private Paint paintBorder; // region Constructor & Init Method public CircularImageView(final Context context) { this(context, null); } public CircularImageView(Context context, AttributeSet attrs) { this(context, attrs, R.attr.circularImageViewStyle); } public CircularImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context, attrs, defStyleAttr); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) public CircularImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); init(context, attrs, defStyleAttr); } private void init(Context context, AttributeSet attrs, int defStyleAttr) { // Init paint paint = new Paint(); paint.setAntiAlias(true); paintBorder = new Paint(); paintBorder.setAntiAlias(true); // Load the styled attributes and set their properties TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.CircularImageView, defStyleAttr, 0); // Init Border if (attributes.getBoolean(R.styleable.CircularImageView_border, true)) { int defaultBorderSize = (int) (4 * getContext().getResources().getDisplayMetrics().density + 0.5f); setBorderWidth(attributes.getDimensionPixelOffset(R.styleable.CircularImageView_border_width, defaultBorderSize)); setBorderColor(attributes.getColor(R.styleable.CircularImageView_border_color, Color.WHITE)); } // Init Shadow if (attributes.getBoolean(R.styleable.CircularImageView_shadow, false)) { drawShadow(attributes.getFloat(R.styleable.CircularImageView_shadow_radius, shadowRadius), attributes.getColor(R.styleable.CircularImageView_shadow_color, shadowColor)); } } //endregion //region Set Attr Method public void setBorderWidth(int borderWidth) { this.borderWidth = borderWidth; this.requestLayout(); this.invalidate(); } public void setBorderColor(int borderColor) { if (paintBorder != null) paintBorder.setColor(borderColor); this.invalidate(); } public void addShadow() { drawShadow(shadowRadius, shadowColor); this.invalidate(); } public void setShadowRadius(float shadowRadius) { drawShadow(shadowRadius, shadowColor); this.invalidate(); } public void setShadowColor(int shadowColor) { drawShadow(shadowRadius, shadowColor); this.invalidate(); } //endregion //region Draw Method @Override public void onDraw(Canvas canvas) { // Load the bitmap loadBitmap(); // Check if image isn't null if (image == null) return; canvasSize = canvas.getWidth(); if (canvas.getHeight() < canvasSize) { canvasSize = canvas.getHeight(); } // circleCenter is the x or y of the view's center // radius is the radius in pixels of the cirle to be drawn // paint contains the shader that will texture the shape int circleCenter = (canvasSize - (borderWidth * 2)) / 2; canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter + borderWidth - (shadowRadius+shadowRadius/2), paintBorder); canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter - (shadowRadius+shadowRadius/2), paint); } private void loadBitmap() { if (this.drawable == getDrawable()) return; this.drawable = getDrawable(); this.image = drawableToBitmap(this.drawable); updateShader(); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); canvasSize = w; if (h < canvasSize) canvasSize = h; if (image != null) updateShader(); } private void drawShadow(float shadowRadius, int shadowColor) { this.shadowRadius = shadowRadius; this.shadowColor = shadowColor; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { setLayerType(LAYER_TYPE_SOFTWARE, paintBorder); } paintBorder.setShadowLayer(shadowRadius, 0.0f, shadowRadius / 2, shadowColor); } private void updateShader() { if (this.image == null) return; final BitmapShader shader = new BitmapShader(Bitmap.createScaledBitmap( ThumbnailUtils.extractThumbnail(image, canvasSize, canvasSize), canvasSize, canvasSize, false), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); paint.setShader(shader); } private Bitmap drawableToBitmap(Drawable drawable) { if (drawable == null) { return null; } else if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable) drawable).getBitmap(); } int intrinsicWidth = drawable.getIntrinsicWidth(); int intrinsicHeight = drawable.getIntrinsicHeight(); if (!(intrinsicWidth > 0 && intrinsicHeight > 0)) return null; try { // Create Bitmap object out of the drawable Bitmap bitmap = Bitmap.createBitmap(intrinsicWidth, intrinsicHeight, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } catch (OutOfMemoryError e) { // Simply return null of failed bitmap creations Log.e(getClass().toString(), "Encountered OutOfMemoryError while generating bitmap!"); return null; } } //endregion //region Mesure Method @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = measureWidth(widthMeasureSpec); int height = measureHeight(heightMeasureSpec); setMeasuredDimension(width, height); } private int measureWidth(int measureSpec) { int result; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); if (specMode == MeasureSpec.EXACTLY) { // The parent has determined an exact size for the child. result = specSize; } else if (specMode == MeasureSpec.AT_MOST) { // The child can be as large as it wants up to the specified size. result = specSize; } else { // The parent has not imposed any constraint on the child. result = canvasSize; } return result; } private int measureHeight(int measureSpecHeight) { int result; int specMode = MeasureSpec.getMode(measureSpecHeight); int specSize = MeasureSpec.getSize(measureSpecHeight); if (specMode == MeasureSpec.EXACTLY) { // We were told how big to be result = specSize; } else if (specMode == MeasureSpec.AT_MOST) { // The child can be as large as it wants up to the specified size. result = specSize; } else { // Measure the text (beware: ascent is a negative number) result = canvasSize; } return (result + 2); } //endregion}
No comments:
Post a Comment