CircleImageView.class package com.example.bean; import com.example.indicator.R; 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.Matrix; import android.graphics.Paint; import android.graphics.RectF; import android.graphics.Shader; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.widget.ImageView; /** * 鍦嗗舰鍥剧墖 * @author Wang.J.L * */ public class CircleImageView extends ImageView { private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP; private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888; private static final int COLORDRAWABLE_DIMENSION = 1; private static final int DEFAULT_BORDER_WIDTH = 0; /** * 鍥剧墖澶栧湀鐨勯鑹? */ private static final int DEFAULT_BORDER_COLOR = Color.WHITE; private final RectF mDrawableRect = new RectF(); private final RectF mBorderRect = new RectF(); private final Matrix mShaderMatrix = new Matrix(); private final Paint mBitmapPaint = new Paint(); private final Paint mBorderPaint = new Paint(); private int mBorderColor = DEFAULT_BORDER_COLOR; private int mBorderWidth = DEFAULT_BORDER_WIDTH; private Bitmap mBitmap; private BitmapShader mBitmapShader; private int mBitmapWidth; private int mBitmapHeight; private float mDrawableRadius; private float mBorderRadius; private boolean mReady; private boolean mSetupPending; public CircleImageView(Context context) { super(context); } public CircleImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CircleImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); super.setScaleType(SCALE_TYPE); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0); mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_border_width, DEFAULT_BORDER_WIDTH); mBorderColor = a.getColor(R.styleable.CircleImageView_border_color, DEFAULT_BORDER_COLOR); a.recycle(); mReady = true; if (mSetupPending) { setup(); mSetupPending = false; } } @Override public ScaleType getScaleType() { return SCALE_TYPE; } @Override public void setScaleType(ScaleType scaleType) { if (scaleType != SCALE_TYPE) { throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType)); } } @Override protected void onDraw(Canvas canvas) { if (getDrawable() == null) { return; } canvas.drawCircle(getWidth() / 2, getHeight() / 2, mDrawableRadius, mBitmapPaint); canvas.drawCircle(getWidth() / 2, getHeight() / 2, mBorderRadius, mBorderPaint); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); setup(); } public int getBorderColor() { return mBorderColor; } public void setBorderColor(int borderColor) { if (borderColor == mBorderColor) { return; } mBorderColor = borderColor; mBorderPaint.setColor(mBorderColor); invalidate(); } public int getBorderWidth() { return mBorderWidth; } public void setBorderWidth(int borderWidth) { if (borderWidth == mBorderWidth) { return; } mBorderWidth = borderWidth; setup(); } @Override public void setImageBitmap(Bitmap bm) { super.setImageBitmap(bm); mBitmap = bm; setup(); } @Override public void setImageDrawable(Drawable drawable) { super.setImageDrawable(drawable); mBitmap = getBitmapFromDrawable(drawable); setup(); } @Override public void setImageResource(int resId) { super.setImageResource(resId); mBitmap = getBitmapFromDrawable(getDrawable()); setup(); } private Bitmap getBitmapFromDrawable(Drawable drawable) { if (drawable == null) { return null; } if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable) drawable).getBitmap(); } try { Bitmap bitmap; if (drawable instanceof ColorDrawable) { bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG); } else { bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG); } Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } catch (OutOfMemoryError e) { return null; } } private void setup() { if (!mReady) { mSetupPending = true; return; } if (mBitmap == null) { return; } mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); mBitmapPaint.setAntiAlias(true); mBitmapPaint.setShader(mBitmapShader); mBorderPaint.setStyle(Paint.Style.STROKE); mBorderPaint.setAntiAlias(true); mBorderPaint.setColor(mBorderColor); mBorderPaint.setStrokeWidth(mBorderWidth); mBitmapHeight = mBitmap.getHeight(); mBitmapWidth = mBitmap.getWidth(); mBorderRect.set(0, 0, getWidth(), getHeight()); mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2, (mBorderRect.width() - mBorderWidth) / 2); mDrawableRect.set(mBorderWidth, mBorderWidth, mBorderRect.width() - mBorderWidth, mBorderRect.height() - mBorderWidth); mDrawableRadius = Math.min(mDrawableRect.height() / 2, mDrawableRect.width() / 2); updateShaderMatrix(); invalidate(); } private void updateShaderMatrix() { float scale; float dx = 0; float dy = 0; mShaderMatrix.set(null); if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) { scale = mDrawableRect.height() / (float) mBitmapHeight; dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f; } else { scale = mDrawableRect.width() / (float) mBitmapWidth; dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f; } mShaderMatrix.setScale(scale, scale); mShaderMatrix.postTranslate((int) (dx + 0.5f) + mBorderWidth, (int) (dy + 0.5f) + mBorderWidth); mBitmapShader.setLocalMatrix(mShaderMatrix); } }
values 下新建attrs.xml <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="RotateTextView"> <attr name="degree" format="dimension" /> </declare-styleable> <declare-styleable name="CircleImageView"> <attr name="border_width" format="dimension" /> <attr name="border_color" format="color" /> </declare-styleable> <declare-styleable name="CropImageView"> <attr name="guidelines"> <enum name="on" value="2" /> <enum name="onTouch" value="1" /> <enum name="off" value="0" /> </attr> <attr name="fixAspectRatio" format="boolean" /> <attr name="aspectRatioX" format="integer" /> <attr name="aspectRatioY" format="integer" /> <attr name="imageResource" format="reference" /> </declare-styleable> </resources>
相关推荐
Glide与CircleImageView加载圆形图片的问题详解 在 Android 开发中,加载圆形图片是一个常见的问题,Glide 和 CircleImageView 是两个常用的解决方案。但是,在实际开发中,我们可能会遇到一些奇怪的问题,例如第一...
本篇将详细讲解如何实现一个自定义的圆形头像视图`CircleImageView`,它能够直接加载网络图片,并且将图片转换为圆形显示,避免了图片裁剪的繁琐步骤。 首先,我们需要创建一个名为`CircleImageView`的类,让它继承...
在代码中,可以通过 findViewById 获取 CircleImageView 实例,并进行进一步的操作,例如加载网络图片: ```java CircleImageView profileImage = findViewById(R.id.profile_image); Glide.with(this) .load(...
在使用时,只需替换原来的ImageView为CircleImageView,并正常加载网络图片。 结合上述知识点,我们可以在`ImageViewLoadAndSetSizeAndCircle.java`这个文件中看到如何将这些功能整合到一起。这个文件可能包含了...
如果你需要动态加载网络图片,可以结合Glide或Picasso等图片加载库使用: ```java Glide.with(this) .load("https://example.com/avatar.jpg") .into(profileImage); ``` `CircleImageView`自定义控件不仅提供了...
本文将详细介绍如何实现一个可以加载本地和网络图片的圆形ImageView控件,以及封装过程中涉及的关键技术。 首先,我们创建一个新的自定义View类,让它继承自Android系统自带的ImageView。这样,我们可以利用...
在Android开发中,加载相册图片是一个常见的需求,特别是在创建一个照片选择或分享应用时。本教程将聚焦于如何从用户设备的系统相册中获取并显示图片到一个GridView中。GridView是一个可以自定义列数并且能根据内容...
在Android开发中,创建圆形头像是常见的需求,用于展示用户头像或者其他需要圆形显示的图片。CircleImageView是一个专为此目的设计...在实际开发中,还可以根据需求进一步扩展,比如添加动画效果、支持加载网络图片等。
在Android开发中,有时我们需要将用户的头像或者其他的图片显示为圆形,以达到更好的视觉效果。CircleImageView是一个非常...在实际开发中,结合图片加载库,如Glide或Picasso,可以进一步优化图片的加载和显示效果。
在Android开发中,创建圆形头像是一个常见的需求,特别是在用户界面设计中,如社交应用、个人资料等场景。本文将详细介绍两种实现...无论哪种方式,都要确保图片的质量和性能优化,尤其是在处理大图或动态加载图片时。
CircleImageView是一个自定义的ImageView子类,它能够将加载的图片自动转换为圆形,同时支持边框宽度和颜色的自定义。 首先,我们需要创建一个属性文件`attrs.xml`,用于存储自定义控件的属性。在项目的`values`...
`CircleImageView`的主要功能是将加载的图片自动转换为圆形,避免了手动处理图像数据的复杂过程。通过这个库,开发者可以避免在XML布局文件中进行复杂的形状绘制,或者在代码中进行像素级的裁剪操作。这样既节省了...
在Android开发中,图片的展示是一项常见的任务,而圆角或者圆形图片的处理则更为特殊。...在实际应用中,根据项目需求,还可以进一步扩展这个CircleImageView,比如增加动画效果、支持加载网络图片等。
在Android应用开发中,图片加载库是不可或缺的一部分,它们能够高效地管理图片资源,优化内存使用,以及提供各种自定义选项来适应不同的显示需求。Glide是一个非常流行的Android图片加载库,它以其简洁的API和出色的...