一、常見問題
圓形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-tw/n/186381.html