广告
返回顶部
首页 > 资讯 > 精选 >Android中怎么通过自定义View实现圆形切图效果
  • 624
分享到

Android中怎么通过自定义View实现圆形切图效果

2023-05-30 16:05:47 624人浏览 薄情痞子
摘要

本篇文章给大家分享的是有关Android中怎么通过自定义View实现圆形切图效果,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。实现思路使用一个Paint,将得到的Bitmap设

本篇文章给大家分享的是有关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; }


计算边距

  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,防止只显示图片边角

  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); }

完整代码

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(); }  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); }  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实现圆形切图效果,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注编程网精选频道。

--结束END--

本文标题: Android中怎么通过自定义View实现圆形切图效果

本文链接: https://www.lsjlt.com/news/219836.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android中怎么通过自定义View实现圆形切图效果
    本篇文章给大家分享的是有关Android中怎么通过自定义View实现圆形切图效果,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。实现思路使用一个Paint,将得到的Bitmap设...
    99+
    2023-05-30
  • Android自定义view实现圆形进度条效果
    Android中实现进度条有很多种方式,自定义进度条一般是继承progressBar或继承view来实现,本篇中讲解的是第二种方式。 先上效果图: 实现圆形进度条总体来说并不难,还...
    99+
    2022-11-13
  • Android中怎么通过自定义View实现画圆
    Android中怎么通过自定义View实现画圆,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。引入布局<xml version="1.0...
    99+
    2023-05-30
    android
  • Android中怎么通过自定义view实现TopBar效果
    这篇文章给大家介绍Android中怎么通过自定义view实现TopBar效果,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。布局文件<xml version="1.0" en...
    99+
    2023-05-30
    android view topbar
  • Android自定义View实现简单的圆形Progress效果
    先给大家展示下效果图,如果感觉不错,请参考实现思路: 我们要实现一个自定义的再一个圆形中绘制一个弧形的自定义View,思路是这样的:   先要创建一个类ProgressVie...
    99+
    2022-06-06
    view progress Android
  • Android自定义view实现半圆环效果
    本文实例为大家分享了Android自定义view实现半圆环的具体代码,供大家参考,具体内容如下 1.自定义属性 <declare-styleable name="Semicir...
    99+
    2022-11-13
  • Android怎么自定义View实现圆弧进度效果
    这篇文章主要介绍“Android怎么自定义View实现圆弧进度效果”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Android怎么自定义View实现圆弧进度效果”文章能帮助大家解决问题。技术实现Ar...
    99+
    2023-07-06
  • Android自定义view实现圆形、圆角和椭圆图片(BitmapShader图形渲染)
    一、前言 Android实现圆角矩形,圆形或者椭圆等图形,一般主要是个自定义View加上使用Xfermode实现的。实现圆角图片的方法其实不少,常见的就是利用Xfermode,...
    99+
    2022-06-06
    view 图片 椭圆 Android
  • 怎么在Android中通过自定义View实现一个箭头沿圆转动效果
    这篇文章主要为大家详细介绍了怎么在Android中通过自定义View实现一个箭头沿圆转动效果,文中示例代码介绍的非常详细,具有一定的参考价值,发现的小伙伴们可以参考一下:Android是什么Android是一种基于Linux内核的自由及开放...
    99+
    2023-05-30
    android view
  • Android自定义View实现圆环交替效果
    下面请先看效果图:    看上去是不很炫的样子,它的实现上也不是很复杂,重点在与onDraw()方法的绘制。 首先是我们的attrs文件: <?xml ver...
    99+
    2022-06-06
    view Android
  • Android如何实现自定义view画圆效果
    这篇文章主要介绍了Android如何实现自定义view画圆效果,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。看图代码:package sjx.com.custonv...
    99+
    2023-05-30
    android view
  • 怎么在Android中通过自定义View实现一个环形进度条效果
    这篇文章给大家介绍怎么在Android中通过自定义View实现一个环形进度条效果,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。功能分析虽然功能比较简单,但是仍然需要仔细分析    ...
    99+
    2023-05-31
    android view roi
  • Android中怎么自定义view实现圆环进度条效果
    这篇文章主要讲解了“Android中怎么自定义view实现圆环进度条效果”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Android中怎么自定义view实现圆环进度条效果”吧!核心代码自定义...
    99+
    2023-06-29
  • Android怎么自定义View实现圆形进度条
    本文小编为大家详细介绍“Android怎么自定义View实现圆形进度条”,内容详细,步骤清晰,细节处理妥当,希望这篇“Android怎么自定义View实现圆形进度条”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。原...
    99+
    2023-07-02
  • 在Android开发中通过自定义View实现一个圆形进度条
    这期内容当中小编将会给大家带来有关在Android开发中通过自定义View实现一个圆形进度条,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。首先来看看自己定义的Viewpackage cn.easymobi...
    99+
    2023-05-31
    android view roi
  • Android如何自定义view实现半圆环效果
    小编给大家分享一下Android如何自定义view实现半圆环效果,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!具体内容如下1.自定义属性<declare-s...
    99+
    2023-06-29
  • Android自定义view实现圆环进度条效果
    本文实例为大家分享了Android自定义view实现圆环进度条效果的具体代码,供大家参考,具体内容如下 一、实现效果图 二、核心代码 自定义view的属性 <xml vers...
    99+
    2022-11-13
  • 怎么在Android中通过自定义View实现一个抽屉效果
    怎么在Android中通过自定义View实现一个抽屉效果?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Android 自定义View实现抽屉效果说明这个自定义V...
    99+
    2023-05-31
    android view roi
  • 怎么在Android中通过自定义View实现一个扫描效果
    这篇文章给大家介绍怎么在Android中通过自定义View实现一个扫描效果,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。自定义属性:<declare-styleable name="ScanV...
    99+
    2023-06-14
  • Android中怎么通过自定义view实现进度条加载效果
    Android中怎么通过自定义view实现进度条加载效果,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。分析图:代码如下:package com.example.d...
    99+
    2023-05-30
    android view
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作