Android开发之---圆形ImageView头像

来源:互联网 发布:终结者创世纪知乎 编辑:程序博客网 时间:2024/05/01 16:26

自定义圆形头像 拿走即可使用

public class RounderdImageView extends ImageView {    public static final String TAG = "SelectableRoundedImageView";    private int mResource = 0;    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    };    // Set default scale type to FIT_CENTER, which is default scale type of    // original ImageView.    private ScaleType mScaleType = ScaleType.CENTER_CROP;    private float mLeftTopCornerRadius = 0.0f;    private float mRightTopCornerRadius = 0.0f;    private float mLeftBottomCornerRadius = 0.0f;    private float mRightBottomCornerRadius = 0.0f;    private float mBorderWidth = 0.0f;    private static final int DEFAULT_BORDER_COLOR = Color.TRANSPARENT;    private ColorStateList mBorderColor = ColorStateList.valueOf(DEFAULT_BORDER_COLOR);    private boolean isOval = false;    private Drawable mDrawable;    private float[] mRadii = new float[] { 0, 0, 0, 0, 0, 0, 0, 0 };    public RounderdImageView(Context context) {        super(context);    }    public RounderdImageView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public RounderdImageView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        TypedArray a = context.obtainStyledAttributes(attrs,                R.styleable.RounderdImageView, defStyle, 0);        final int index = a.getInt(R.styleable.RounderdImageView_android_scaleType, -1);        if (index >= 0) {            setScaleType(sScaleTypeArray[index]);        }        mLeftTopCornerRadius = a.getDimensionPixelSize(                R.styleable.RounderdImageView_sriv_left_top_corner_radius, 0);        mRightTopCornerRadius = a.getDimensionPixelSize(                R.styleable.RounderdImageView_sriv_right_top_corner_radius, 0);        mLeftBottomCornerRadius = a.getDimensionPixelSize(                R.styleable.RounderdImageView_sriv_left_bottom_corner_radius, 0);        mRightBottomCornerRadius = a.getDimensionPixelSize(                R.styleable.RounderdImageView_sriv_right_bottom_corner_radius, 0);                if (mLeftTopCornerRadius < 0.0f || mRightTopCornerRadius < 0.0f                || mLeftBottomCornerRadius < 0.0f || mRightBottomCornerRadius < 0.0f) {            throw new IllegalArgumentException("radius values cannot be negative.");        }                mRadii = new float[] {                 mLeftTopCornerRadius, mLeftTopCornerRadius,                mRightTopCornerRadius, mRightTopCornerRadius,                 mRightBottomCornerRadius, mRightBottomCornerRadius,                 mLeftBottomCornerRadius, mLeftBottomCornerRadius };        mBorderWidth = a.getDimensionPixelSize(                R.styleable.RounderdImageView_sriv_border_width, 0);        if (mBorderWidth < 0) {            throw new IllegalArgumentException("border width cannot be negative.");        }        mBorderColor = a                .getColorStateList(R.styleable.RounderdImageView_sriv_border_color);        if (mBorderColor == null) {            mBorderColor = ColorStateList.valueOf(DEFAULT_BORDER_COLOR);        }        isOval = a.getBoolean(R.styleable.RounderdImageView_sriv_oval, false);        a.recycle();                updateDrawable();    }    @Override    protected void drawableStateChanged() {        super.drawableStateChanged();        invalidate();    }    @Override    public ScaleType getScaleType() {        return mScaleType;    }    @Override    public void setScaleType(ScaleType scaleType) {        super.setScaleType(scaleType);        mScaleType = scaleType;        updateDrawable();    }    @Override    public void setImageDrawable(Drawable drawable) {        mResource = 0;        mDrawable = SelectableRoundedCornerDrawable.fromDrawable(drawable, getResources());        super.setImageDrawable(mDrawable);        updateDrawable();    }    @Override    public void setImageBitmap(Bitmap bm) {        mResource = 0;        mDrawable = SelectableRoundedCornerDrawable.fromBitmap(bm, getResources());        super.setImageDrawable(mDrawable);        updateDrawable();    }    @Override    public void setImageResource(int resId) {        if (mResource != resId) {            mResource = resId;            mDrawable = resolveResource();            super.setImageDrawable(mDrawable);            updateDrawable();        }    }    @Override    public void setImageURI(Uri uri) {        super.setImageURI(uri);        setImageDrawable(getDrawable());    }    private Drawable resolveResource() {        Resources rsrc = getResources();        if (rsrc == null) {            return null;        }        Drawable d = null;        if (mResource != 0) {            try {                d = rsrc.getDrawable(mResource);            } catch (NotFoundException e) {                // Don't try again.                mResource = 0;            }        }        return SelectableRoundedCornerDrawable.fromDrawable(d, getResources());    }    private void updateDrawable() {        if (mDrawable == null) {            return;        }        ((SelectableRoundedCornerDrawable) mDrawable).setScaleType(mScaleType);        ((SelectableRoundedCornerDrawable) mDrawable).setCornerRadii(mRadii);        ((SelectableRoundedCornerDrawable) mDrawable).setBorderWidth(mBorderWidth);        ((SelectableRoundedCornerDrawable) mDrawable).setBorderColor(mBorderColor);        ((SelectableRoundedCornerDrawable) mDrawable).setOval(isOval);    }    public float getCornerRadius() {        return mLeftTopCornerRadius;    }    /**     * Set radii for each corner.     *      * @param leftTop The desired radius for left-top corner in dip.     * @param rightTop The desired desired radius for right-top corner in dip.     * @param leftBottom The desired radius for left-bottom corner in dip.     * @param rightBottom The desired radius for right-bottom corner in dip.     *      */    public void setCornerRadiiDP(float leftTop, float rightTop, float leftBottom, float rightBottom) {        final float density = getResources().getDisplayMetrics().density;                final float lt = leftTop * density;        final float rt = rightTop * density;        final float lb = leftBottom * density;        final float rb = rightBottom * density;                mRadii = new float[] { lt, lt, rt, rt, rb, rb, lb, lb };        updateDrawable();    }    public float getBorderWidth() {        return mBorderWidth;    }    /**     * Set border width.     *      * @param width     *            The desired width in dip.     */    public void setBorderWidthDP(float width) {        float scaledWidth = getResources().getDisplayMetrics().density * width;         if (mBorderWidth == scaledWidth) {            return;        }        mBorderWidth = scaledWidth;        updateDrawable();        invalidate();    }    public int getBorderColor() {        return mBorderColor.getDefaultColor();    }    public void setBorderColor(int color) {        setBorderColor(ColorStateList.valueOf(color));    }    public ColorStateList getBorderColors() {        return mBorderColor;    }    public void setBorderColor(ColorStateList colors) {        if (mBorderColor.equals(colors)) {            return;        }        mBorderColor = (colors != null) ? colors : ColorStateList                .valueOf(DEFAULT_BORDER_COLOR);        updateDrawable();        if (mBorderWidth > 0) {            invalidate();        }    }    public boolean isOval() {        return isOval;    }    public void setOval(boolean oval) {        isOval = oval;        updateDrawable();        invalidate();    }    static class SelectableRoundedCornerDrawable extends Drawable {        private static final String TAG = "SelectableRoundedCornerDrawable";        private static final int DEFAULT_BORDER_COLOR = Color.BLACK;        private RectF mBounds = new RectF();        private RectF mBorderBounds = new RectF();        private final RectF mBitmapRect = new RectF();        private final int mBitmapWidth;        private final int mBitmapHeight;        private final Paint mBitmapPaint;        private final Paint mBorderPaint;        private BitmapShader mBitmapShader;        private float[] mRadii = new float[] { 0, 0, 0, 0, 0, 0, 0, 0 };        private float[] mBorderRadii = new float[] { 0, 0, 0, 0, 0, 0, 0, 0 };        private boolean mOval = false;        private float mBorderWidth = 0;        private ColorStateList mBorderColor = ColorStateList.valueOf(DEFAULT_BORDER_COLOR);        // Set default scale type to FIT_CENTER, which is default scale type of        // original ImageView.        private ScaleType mScaleType = ScaleType.FIT_CENTER;        private Path mPath = new Path();        private Bitmap mBitmap;        private boolean mBoundsConfigured = false;        public SelectableRoundedCornerDrawable(Bitmap bitmap, Resources r) {            mBitmap = bitmap;            mBitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);            if (bitmap != null) {                mBitmapWidth = bitmap.getScaledWidth(r.getDisplayMetrics());                mBitmapHeight = bitmap.getScaledHeight(r.getDisplayMetrics());            } else {                mBitmapWidth = mBitmapHeight = -1;            }            mBitmapRect.set(0, 0, mBitmapWidth, mBitmapHeight);            mBitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG);            mBitmapPaint.setStyle(Paint.Style.FILL);            mBitmapPaint.setShader(mBitmapShader);            mBorderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);            mBorderPaint.setStyle(Paint.Style.STROKE);            mBorderPaint.setColor(mBorderColor.getColorForState(getState(), DEFAULT_BORDER_COLOR));            mBorderPaint.setStrokeWidth(mBorderWidth);        }        public static SelectableRoundedCornerDrawable fromBitmap(Bitmap bitmap, Resources r) {            if (bitmap != null) {                return new SelectableRoundedCornerDrawable(bitmap, r);            } else {                return null;            }        }        public static Drawable fromDrawable(Drawable drawable, Resources r) {            if (drawable != null) {                if (drawable instanceof SelectableRoundedCornerDrawable) {                    return drawable;                } else if (drawable instanceof LayerDrawable) {                    LayerDrawable ld = (LayerDrawable) drawable;                    final int num = ld.getNumberOfLayers();                    for (int i = 0; i < num; i++) {                        Drawable d = ld.getDrawable(i);                        ld.setDrawableByLayerId(ld.getId(i), fromDrawable(d, r));                    }                    return ld;                }                Bitmap bm = drawableToBitmap(drawable);                if (bm != null) {                    return new SelectableRoundedCornerDrawable(bm, r);                } else {                    Log.d(TAG, "Failed to create bitmap from drawable!");                }            }            return drawable;        }        public static Bitmap drawableToBitmap(Drawable drawable) {            if (drawable == null) {                return null;            }            if (drawable instanceof BitmapDrawable) {                return ((BitmapDrawable) drawable).getBitmap();            }            Bitmap bitmap;            int width = Math.max(drawable.getIntrinsicWidth(), 2);            int height = Math.max(drawable.getIntrinsicHeight(), 2);            try {                bitmap = Bitmap.createBitmap(width, height, Config.RGB_565);                Canvas canvas = new Canvas(bitmap);                drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());                drawable.draw(canvas);            } catch (IllegalArgumentException e) {                e.printStackTrace();                bitmap = null;            }            return bitmap;        }        @Override        public boolean isStateful() {            return mBorderColor.isStateful();        }        @Override        protected boolean onStateChange(int[] state) {            int newColor = mBorderColor.getColorForState(state, 0);            if (mBorderPaint.getColor() != newColor) {                mBorderPaint.setColor(newColor);                return true;            } else {                return super.onStateChange(state);            }        }        private void configureBounds(Canvas canvas) {            // I have discovered a truly marvelous explanation of this,            // which this comment space is too narrow to contain. :)            // If you want to understand what's going on here,            // See http://www.joooooooooonhokim.com/?p=289            Rect clipBounds = canvas.getClipBounds();            Matrix canvasMatrix = canvas.getMatrix();            if (ScaleType.CENTER == mScaleType) {                mBounds.set(clipBounds);            } else if (ScaleType.CENTER_CROP == mScaleType) {                applyScaleToRadii(canvasMatrix);                mBounds.set(clipBounds);            } else if (ScaleType.FIT_XY == mScaleType) {                Matrix m = new Matrix();                m.setRectToRect(mBitmapRect, new RectF(clipBounds), Matrix.ScaleToFit.FILL);                mBitmapShader.setLocalMatrix(m);                mBounds.set(clipBounds);            } else if (ScaleType.FIT_START == mScaleType || ScaleType.FIT_END == mScaleType                    || ScaleType.FIT_CENTER == mScaleType || ScaleType.CENTER_INSIDE == mScaleType) {                applyScaleToRadii(canvasMatrix);                mBounds.set(mBitmapRect);            } else if (ScaleType.MATRIX == mScaleType) {                applyScaleToRadii(canvasMatrix);                mBounds.set(mBitmapRect);            }        }        private void applyScaleToRadii(Matrix m) {            float[] values = new float[9];            m.getValues(values);            for (int i = 0; i < mRadii.length; i++) {                mRadii[i] = mRadii[i] / values[0];            }        }        private void adjustCanvasForBorder(Canvas canvas) {            Matrix canvasMatrix = canvas.getMatrix();            final float[] values = new float[9];            canvasMatrix.getValues(values);            final float scaleFactorX = values[0];            final float scaleFactorY = values[4];            final float translateX = values[2];            final float translateY = values[5];            final float newScaleX = mBounds.width()                    / (mBounds.width() + mBorderWidth + mBorderWidth);            final float newScaleY = mBounds.height()                    / (mBounds.height() + mBorderWidth + mBorderWidth);            canvas.scale(newScaleX, newScaleY);            if (ScaleType.FIT_START == mScaleType || ScaleType.FIT_END == mScaleType                    || ScaleType.FIT_XY == mScaleType || ScaleType.FIT_CENTER == mScaleType                    || ScaleType.CENTER_INSIDE == mScaleType || ScaleType.MATRIX == mScaleType) {                canvas.translate(mBorderWidth, mBorderWidth);            } else if (ScaleType.CENTER == mScaleType || ScaleType.CENTER_CROP == mScaleType) {                // First, make translate values to 0                canvas.translate(                        -translateX / (newScaleX * scaleFactorX),                         -translateY / (newScaleY * scaleFactorY));                // Then, set the final translate values.                canvas.translate(-(mBounds.left - mBorderWidth), -(mBounds.top - mBorderWidth));            }         }        private void adjustBorderWidthAndBorderBounds(Canvas canvas) {            Matrix canvasMatrix = canvas.getMatrix();            final float[] values = new float[9];            canvasMatrix.getValues(values);            final float scaleFactor = values[0];            float viewWidth = mBounds.width() * scaleFactor;            mBorderWidth = (mBorderWidth * mBounds.width()) / (viewWidth - (2 * mBorderWidth));            mBorderPaint.setStrokeWidth(mBorderWidth);            mBorderBounds.set(mBounds);            mBorderBounds.inset(- mBorderWidth / 2, - mBorderWidth / 2);        }        private void setBorderRadii() {            for (int i = 0; i < mRadii.length; i++) {                if (mRadii[i] > 0) {                    mBorderRadii[i] = mRadii[i];                    mRadii[i] = mRadii[i] - mBorderWidth;                }            }        }        @Override        public void draw(Canvas canvas) {            canvas.save();            if (!mBoundsConfigured) {                configureBounds(canvas);                if (mBorderWidth > 0) {                    adjustBorderWidthAndBorderBounds(canvas);                    setBorderRadii();                }                mBoundsConfigured = true;            }            if (mOval) {                if (mBorderWidth > 0) {                    adjustCanvasForBorder(canvas);                    mPath.addOval(mBounds, Path.Direction.CW);                    canvas.drawPath(mPath, mBitmapPaint);                    mPath.reset();                    mPath.addOval(mBorderBounds, Path.Direction.CW);                    canvas.drawPath(mPath, mBorderPaint);                } else {                    mPath.addOval(mBounds, Path.Direction.CW);                    canvas.drawPath(mPath, mBitmapPaint);                }            } else {                if (mBorderWidth > 0) {                    adjustCanvasForBorder(canvas);                    mPath.addRoundRect(mBounds, mRadii, Path.Direction.CW);                    canvas.drawPath(mPath, mBitmapPaint);                    mPath.reset();                    mPath.addRoundRect(mBorderBounds, mBorderRadii, Path.Direction.CW);                    canvas.drawPath(mPath, mBorderPaint);                } else {                    mPath.addRoundRect(mBounds, mRadii, Path.Direction.CW);                    canvas.drawPath(mPath, mBitmapPaint);                }            }            canvas.restore();        }        public void setCornerRadii(float[] radii) {            if (radii == null)                return;            if (radii.length != 8) {                throw new ArrayIndexOutOfBoundsException("radii[] needs 8 values");            }            for (int i = 0; i < radii.length; i++) {                mRadii[i] = radii[i];            }        }        @Override        public int getOpacity() {            return (mBitmap == null || mBitmap.hasAlpha() || mBitmapPaint.getAlpha() < 255) ? PixelFormat.TRANSLUCENT                    : PixelFormat.OPAQUE;        }        @Override        public void setAlpha(int alpha) {            mBitmapPaint.setAlpha(alpha);            invalidateSelf();        }        @Override        public void setColorFilter(ColorFilter cf) {            mBitmapPaint.setColorFilter(cf);            invalidateSelf();        }        @Override        public void setDither(boolean dither) {            mBitmapPaint.setDither(dither);            invalidateSelf();        }        @Override        public void setFilterBitmap(boolean filter) {            mBitmapPaint.setFilterBitmap(filter);            invalidateSelf();        }        @Override        public int getIntrinsicWidth() {            return mBitmapWidth;        }        @Override        public int getIntrinsicHeight() {            return mBitmapHeight;        }        public float getBorderWidth() {            return mBorderWidth;        }        public void setBorderWidth(float width) {            mBorderWidth = width;            mBorderPaint.setStrokeWidth(width);        }        public int getBorderColor() {            return mBorderColor.getDefaultColor();        }        public void setBorderColor(int color) {            setBorderColor(ColorStateList.valueOf(color));        }        public ColorStateList getBorderColors() {            return mBorderColor;        }        /**         * Controls border color of this ImageView.         *          * @param colors         *            The desired border color. If it's null, no border will be         *            drawn.         *          */        public void setBorderColor(ColorStateList colors) {            if (colors == null) {                mBorderWidth = 0;                mBorderColor = ColorStateList.valueOf(Color.TRANSPARENT);                mBorderPaint.setColor(Color.TRANSPARENT);            } else {                mBorderColor = colors;                mBorderPaint.setColor(mBorderColor.getColorForState(getState(), DEFAULT_BORDER_COLOR));            }        }        public boolean isOval() {            return mOval;        }        public void setOval(boolean oval) {            mOval = oval;        }        public ScaleType getScaleType() {            return mScaleType;        }        public void setScaleType(ScaleType scaleType) {            if (scaleType == null) {                return;            }            mScaleType = scaleType;        }    }}

使用的时候,直接在布局文件中像imageview一样使用即可

<com.jixiong.teen.view.RounderdImageView    android:id="@+id/rivUserAvatar"    android:layout_width="@dimen/margin_forty_four"    android:layout_height="match_parent"    android:layout_centerVertical="true"    android:src="@drawable/icon_myself_touxiang"    app:sriv_oval="true" />
最后在Java代码中使用

Glide.with(this).load(userBean.avatar).diskCacheStrategy(DiskCacheStrategy.ALL).placeholder(R.drawable.icon_myself_touxiang).into(rivUserAvatar);

0 0
原创粉丝点击