一、常見問題
圓形ImageView是Android開發中比較常見的一個需求,但是Android原生的ImageView並不支持直接繪製圓形,所以需要使用自定義View。
下面是一些常見問題:
1、怎樣繪製一個圓形ImageView?
2、怎樣使圓形ImageView具有邊框?
3、怎樣對圓形ImageView進行動畫操作?
二、原理與實現
繪製一個圓形的ImageView可以分為以下幾步:
1、繼承ImageView
2、重寫onDraw方法,在其中繪製一個圓形的Bitmap
3、設置ImageView的ScaleType為CENTER_CROP,保證圖片的寬高比被保持且填充滿整個View
4、可以根據需求在繪製的Bitmap周圍添加邊框或者做動畫效果
下面是代碼示例:
public class CircleImageView extends ImageView {
private Bitmap mBitmap;
private Paint mPaint;
public CircleImageView(Context context) {
super(context);
init();
}
public CircleImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CircleImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setShader(new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
}
@Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (drawable == null) {
super.onDraw(canvas);
} else {
mBitmap = drawableToBitmap(drawable);
mPaint.setShader(new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
canvas.drawCircle(getWidth() / 2, getHeight() / 2, getWidth() / 2, mPaint);
}
}
private Bitmap drawableToBitmap(Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
}
三、常用功能實現
1、添加邊框
在上面的代碼基礎上,我們可以在繪製Bitmap的周圍添加一些邊框來增強視覺效果。
下面是添加邊框的代碼示例:
public class CircleImageView extends ImageView {
private Bitmap mBitmap;
private Paint mPaint;
private Paint mBorderPaint;
private int mBorderColor;
private int mBorderWidth;
public CircleImageView(Context context) {
super(context);
init();
}
public CircleImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CircleImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyleAttr, 0);
mBorderColor = a.getColor(R.styleable.CircleImageView_borderColor, Color.WHITE);
mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_borderWidth, 0);
a.recycle();
init();
}
private void init() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setShader(new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
mBorderPaint = new Paint();
mBorderPaint.setAntiAlias(true);
mBorderPaint.setColor(mBorderColor);
mBorderPaint.setStyle(Paint.Style.STROKE);
mBorderPaint.setStrokeWidth(mBorderWidth);
}
@Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (drawable == null) {
super.onDraw(canvas);
} else {
mBitmap = drawableToBitmap(drawable);
mPaint.setShader(new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
canvas.drawCircle(getWidth() / 2, getHeight() / 2, getWidth() / 2 - mBorderWidth, mPaint);
canvas.drawCircle(getWidth() / 2, getHeight() / 2, getWidth() / 2 - mBorderWidth / 2, mBorderPaint);
}
}
private Bitmap drawableToBitmap(Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
}
2、添加動畫
我們也可以為這個圓形ImageView添加一些動畫效果,比如旋轉、縮放、漸變等。
下面是旋轉動畫和縮放動畫的代碼示例:
public class CircleImageView extends ImageView {
private Bitmap mBitmap;
private Paint mPaint;
private Matrix mMatrix;
private float mRotation;
private float mScale = 1f;
public CircleImageView(Context context) {
super(context);
init();
}
public CircleImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CircleImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setShader(new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
mMatrix = new Matrix();
}
@Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (drawable == null) {
super.onDraw(canvas);
} else {
mBitmap = drawableToBitmap(drawable);
mPaint.setShader(new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
int width = getWidth();
int height = getHeight();
int size = Math.min(width, height);
mMatrix.reset();
mMatrix.postScale(mScale, mScale);
mMatrix.postRotate(mRotation, size / 2f, size / 2f);
mMatrix.postTranslate((width - size) / 2f, (height - size) / 2f);
canvas.drawCircle(size / 2f, size / 2f, size / 2f, mPaint);
}
}
public void setRotation(float rotation) {
mRotation = rotation;
invalidate();
}
public void setScale(float scale) {
mScale = scale;
invalidate();
}
public void rotate(float from, float to, long duration) {
ObjectAnimator animator = ObjectAnimator.ofFloat(this, "rotation", from, to);
animator.setDuration(duration);
animator.start();
}
public void scale(float from, float to, long duration) {
ValueAnimator animator = ValueAnimator.ofFloat(from, to);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mScale = (float) animation.getAnimatedValue();
invalidate();
}
});
animator.setDuration(duration);
animator.start();
}
private Bitmap drawableToBitmap(Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
}
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/186381.html
微信掃一掃
支付寶掃一掃