中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android中怎么通過自定義View實現圓形切圖效果

發布時間:2021-06-28 17:41:53 來源:億速云 閱讀:151 作者:Leah 欄目:移動開發

本篇文章給大家分享的是有關Android中怎么通過自定義View實現圓形切圖效果,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

實現思路

使用一個Paint,將得到的Bitmap設置成paint的Shader,設置完成后,使用Matrix調整圖片至居中,使用RectF約束邊框,最后完成繪制

初始化Paint,設置Shader

private void init() {
  getBitmapFromDrawable();
  if (mBitmap == null) {
   return;
  }
  mShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

  // bitmap paint
  mFillPaint = new Paint();
  mFillPaint.setAntiAlias(true);
  mFillPaint.setStyle(Paint.Style.FILL);
  mFillPaint.setShader(mShader);

  // border paint
  mBoundPaint = new Paint();
  mBoundPaint.setAntiAlias(true);
  mBoundPaint.setStyle(Paint.Style.STROKE);
  mBoundPaint.setStrokeWidth(mBorderWidth);
  mBoundPaint.setColor(mBorderColor);

  // border rectF
  mBorderBound.set(calculateBitmapBound());

  // bitmap rectF
  mBitmapBound.set(calculateBitmapBound());
  mBitmapBound.inset(mBorderWidth - 10, mBorderWidth - 10);
  updateShaderMatrix();

 }

獲取Drawable

private Bitmap getBitmapFromDrawable() {
  Drawable drawable = getDrawable();
  if (drawable instanceof BitmapDrawable) {
   mBitmap = ((BitmapDrawable) drawable).getBitmap();
   mBitmapWidth = mBitmap.getWidth();
   mBitmapHeight = mBitmap.getHeight();
   return mBitmap;
  }
  return null;
 }


計算邊距

 /**
  * 計算Bitmap邊距
  */
 private RectF calculateBitmapBound() {
  int availableWidth = getWidth() - getPaddingLeft() - getPaddingRight();
  int availableHeight = getHeight() - getPaddingTop() - getPaddingBottom();
  int sideLength = Math.min(availableWidth, availableHeight); // 可用的直徑
  mRadius = sideLength / 2;

  int left = getPaddingLeft() + (availableWidth - sideLength) / 2;
  int top = getPaddingTop() + (availableHeight - sideLength) / 2;

  Log.d(TAG, "calculateBitmapBound: left >>> " + left + " top >>> " + top + " right >>> "
    + (left + sideLength) + " right >>> " + top + " bottom >>> " + (top + sideLength));
  return new RectF(left, top, left + sideLength, top + sideLength);
 }


調整Matrix,防止只顯示圖片邊角

 /**
  * 調整圖片縮放,目前只支持CenterCrop
  */
 private void updateShaderMatrix() {
  float scale;
  float dx = 0;
  float dy = 0;

  mShaderMatrix.set(null);

  // 調整縮放,使圖片居中
  if (mBitmapWidth * mBitmapBound.height() > mBitmapBound.width() * mBitmapHeight) {
   scale = mBitmapBound.height() / (float) mBitmapHeight;
   dx = (mBitmapBound.width() - mBitmapWidth * scale) * 0.5f;
  } else {
   scale = mBitmapBound.width() / (float) mBitmapWidth;
   dy = (mBitmapBound.height() - mBitmapHeight * scale) * 0.5f;
  }

  Log.d(TAG, "updateShaderMatrix: scale >>> " + scale);
  mShaderMatrix.setScale(scale, scale);
  // TODO: 16-10-15 http://chroya.iteye.com/blog/713869
  // 回到中心點,便于下次縮放
  mShaderMatrix.postTranslate((int) (dx + 0.5f) + mBitmapBound.left, (int) (dy + 0.5f) + mBitmapBound.top);

  mShader.setLocalMatrix(mShaderMatrix);
 }

onDraw

 @Override
 protected void onDraw(Canvas canvas) {
  if (mBitmap == null) {
   super.onDraw(canvas);
  }
  Log.d(TAG, "onDraw: centerX >>> " + mBitmapBound.centerX() + " centerY >>> " + mBitmapBound.centerY());
  canvas.drawCircle(mBitmapBound.centerX(), mBitmapBound.centerY(), mRadius, mFillPaint);
  // 繪制邊框
  canvas.drawCircle(mBorderBound.centerX(), mBorderBound.centerY(), mRadius, mBoundPaint);
 }

完整代碼

/**
 * Created by shixi_tianrui1 on 16-10-7.
 * 顯示圓形圖片的ImageView
 */

public class CircleImageView extends ImageView {

 private static final String TAG = "LOGGER";

 private BitmapShader mShader;
 private Paint mFillPaint; // 繪圖
 private Paint mBoundPaint; // 繪制圓邊

 private Bitmap mBitmap;
 private Drawable mDrawable;

 private int mBorderColor;  // 邊框顏色
 private float mBorderWidth;  // 邊框寬度

 private RectF mBorderBound = new RectF();
 private RectF mBitmapBound = new RectF();
 private Matrix mShaderMatrix = new Matrix();

 private int mRadius;
 private int mBitmapWidth;
 private int mBitmapHeight;

 private static final float DEFAULT_BORDER_WIDTH = 5;

 public CircleImageView(Context context) {
  this(context, null);
 }

 public CircleImageView(Context context, AttributeSet attrs) {
  this(context, attrs, 0);
 }

 public CircleImageView(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  TypedArray a = getResources().obtainAttributes(attrs, R.styleable.CircleImageView);
  mBorderColor = a.getColor(R.styleable.CircleImageView_borderColor, Color.BLUE);
  mBorderWidth = a.getDimension(R.styleable.CircleImageView_borderWidth, DEFAULT_BORDER_WIDTH);
  mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_borderWidth, 20);
  a.recycle();
 }

 private void init() {
  getBitmapFromDrawable();
  if (mBitmap == null) {
   return;
  }
  mShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

  // bitmap paint
  mFillPaint = new Paint();
  mFillPaint.setAntiAlias(true);
  mFillPaint.setStyle(Paint.Style.FILL);
  mFillPaint.setShader(mShader);

  // border paint
  mBoundPaint = new Paint();
  mBoundPaint.setAntiAlias(true);
  mBoundPaint.setStyle(Paint.Style.STROKE);
  mBoundPaint.setStrokeWidth(mBorderWidth);
  mBoundPaint.setColor(mBorderColor);

  // border rectF
  mBorderBound.set(calculateBitmapBound());

  // bitmap rectF
  mBitmapBound.set(calculateBitmapBound());
  mBitmapBound.inset(mBorderWidth - 10, mBorderWidth - 10);
  updateShaderMatrix();

 }

 @Override
 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
  super.onSizeChanged(w, h, oldw, oldh);
  init();
 }

 /**
  * 計算Bitmap邊距
  */
 private RectF calculateBitmapBound() {
  int availableWidth = getWidth() - getPaddingLeft() - getPaddingRight();
  int availableHeight = getHeight() - getPaddingTop() - getPaddingBottom();
  int sideLength = Math.min(availableWidth, availableHeight); // 可用的直徑
  mRadius = sideLength / 2;

  int left = getPaddingLeft() + (availableWidth - sideLength) / 2;
  int top = getPaddingTop() + (availableHeight - sideLength) / 2;

  Log.d(TAG, "calculateBitmapBound: left >>> " + left + " top >>> " + top + " right >>> "
    + (left + sideLength) + " right >>> " + top + " bottom >>> " + (top + sideLength));
  return new RectF(left, top, left + sideLength, top + sideLength);
 }


 private Bitmap getBitmapFromDrawable() {
  Drawable drawable = getDrawable();
  if (drawable instanceof BitmapDrawable) {
   mBitmap = ((BitmapDrawable) drawable).getBitmap();
   mBitmapWidth = mBitmap.getWidth();
   mBitmapHeight = mBitmap.getHeight();
   return mBitmap;
  }
  return null;
 }

 @Override
 protected void onDraw(Canvas canvas) {
  if (mBitmap == null) {
   super.onDraw(canvas);
  }
  Log.d(TAG, "onDraw: centerX >>> " + mBitmapBound.centerX() + " centerY >>> " + mBitmapBound.centerY());
  canvas.drawCircle(mBitmapBound.centerX(), mBitmapBound.centerY(), mRadius, mFillPaint);
  // 繪制邊框
  canvas.drawCircle(mBorderBound.centerX(), mBorderBound.centerY(), mRadius, mBoundPaint);
 }


 /**
  * 調整圖片縮放,目前只支持CenterCrop
  */
 private void updateShaderMatrix() {
  float scale;
  float dx = 0;
  float dy = 0;

  mShaderMatrix.set(null);

  // 調整縮放,使圖片居中
  if (mBitmapWidth * mBitmapBound.height() > mBitmapBound.width() * mBitmapHeight) {
   scale = mBitmapBound.height() / (float) mBitmapHeight;
   dx = (mBitmapBound.width() - mBitmapWidth * scale) * 0.5f;
  } else {
   scale = mBitmapBound.width() / (float) mBitmapWidth;
   dy = (mBitmapBound.height() - mBitmapHeight * scale) * 0.5f;
  }

  Log.d(TAG, "updateShaderMatrix: scale >>> " + scale);
  mShaderMatrix.setScale(scale, scale);
  // TODO: 16-10-15 http://chroya.iteye.com/blog/713869
  // 回到中心點,便于下次縮放
  mShaderMatrix.postTranslate((int) (dx + 0.5f) + mBitmapBound.left, (int) (dy + 0.5f) + mBitmapBound.top);

  mShader.setLocalMatrix(mShaderMatrix);
 }
}

以上就是Android中怎么通過自定義View實現圓形切圖效果,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

留坝县| 河北省| 尖扎县| 上高县| 新蔡县| 新营市| 且末县| 当阳市| 大渡口区| 麟游县| 布尔津县| 博野县| 德兴市| 桃江县| 云梦县| 浙江省| 肃宁县| 岐山县| 新绛县| 班戈县| 澄江县| 绥棱县| 合作市| 顺昌县| 高雄县| 侯马市| 准格尔旗| 宁乡县| 隆昌县| 缙云县| 衡阳县| 阳新县| 隆安县| 皮山县| 宁武县| 库伦旗| 大连市| 洞头县| 荆门市| 仙居县| 巍山|