解决CircleImageView不能用Afinal的FinalBitmap加载网络图片问题

圆形图片CircleImageView的使用和分析 在项目开发中,我们经常需要用到圆形图片效果,典型案例是用户头像的显示。 如图所示。 下面我们使用开源控件CircleImageView来实现该效果。 CircleImageView项目下载地址: https://github.com/hdodenhof/CircleImageView (1).CircleImageView的使用 首先我们将CircleImage 阅读详情

相信好多项目中都会用到类似QQ头像的圆形ImageView,最近小编在项目就用到这个圆形的ImageView,于是在网上找到了开源项目CircleImageView。用的时候感觉不错,但是在利用Afinal框架的display方法加载网络图片时,总是显示不出来,甚是苦恼。当然解决问题的最好的办法就是读源码,于是我看一下CircleImageView的源码,发现它需

要一个bitmap通过裁剪显示圆形的,而Afinal框架的display方法则不能提供一个bitmap。这时我就找FinalBitmap有没有提供一个方法返回的是bitmap的,很遗憾没有给我们提供这样的方法。后来我查找ImageLoader框架,发现它给我提供了一个这样的方法loadImageSync,它可以通过URL返回的一个bitmap,再把这个bitmap提供CircleImageView就能很好的显示图片了。但是特别要注意的是,loadImageSync这个方法是同步的,不是异步的尴尬,android4.0有个特性,网络操作不能在主线程,意思是这个方法必须要开一个线程操作。不然直接使用会报错的。

这个就是我在CircleImageView中新增的方法

/**
	 * 为圆形Iamge设置IamgeUrl
	 * 
	 * @param url 图片的url
	 */
	public void setImageURL(final String url) {

		final Handler handler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				super.handleMessage(msg);
				setImageBitmap(bitmap);
			}
		};

		/**
		 * 网络操作相关的子线程
		 */
		new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO
				// 在这里进行 http request.网络请求相关操作
				Message msg = new Message();
				bitmap = ImageLoader.getInstance().loadImageSync(url);
				handler.sendMessage(msg);
			}
		}).start();

	}


修改过后的CircleImageView,可以拿去直接使用了大笑

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 = 2;

	private static final int DEFAULT_BORDER_WIDTH = 0;
	private static final int DEFAULT_BORDER_COLOR = Color.BLACK;
	private static final int DEFAULT_FILL_COLOR = Color.TRANSPARENT;
	private static final boolean DEFAULT_BORDER_OVERLAY = false;

	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 final Paint mFillPaint = new Paint();

	private int mBorderColor = DEFAULT_BORDER_COLOR;
	private int mBorderWidth = DEFAULT_BORDER_WIDTH;
	private int mFillColor = DEFAULT_FILL_COLOR;

	private Bitmap mBitmap;
	private BitmapShader mBitmapShader;
	private int mBitmapWidth;
	private int mBitmapHeight;

	private float mDrawableRadius;
	private float mBorderRadius;

	private ColorFilter mColorFilter;

	private boolean mReady;
	private boolean mSetupPending;
	private boolean mBorderOverlay;

	private Context mContext;
	private Bitmap bitmap = null;

	public CircleImageView(Context context) {
		super(context);
		this.mContext = context;
		init();
	}

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

	public CircleImageView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		this.mContext = context;
		TypedArray a = context.obtainStyledAttributes(attrs,
				R.styleable.CircleImageView, defStyle, 0);

		mBorderWidth = a.getDimensionPixelSize(
				R.styleable.CircleImageView_civ_border_width,
				DEFAULT_BORDER_WIDTH);
		mBorderColor = a.getColor(R.styleable.CircleImageView_civ_border_color,
				DEFAULT_BORDER_COLOR);
		mBorderOverlay = a.getBoolean(
				R.styleable.CircleImageView_civ_border_overlay,
				DEFAULT_BORDER_OVERLAY);
		mFillColor = a.getColor(R.styleable.CircleImageView_civ_fill_color,
				DEFAULT_FILL_COLOR);

		a.recycle();

		init();
	}

	private void init() {
		super.setScaleType(SCALE_TYPE);

		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
	public void setAdjustViewBounds(boolean adjustViewBounds) {
		if (adjustViewBounds) {
			throw new IllegalArgumentException(
					"adjustViewBounds not supported.");
		}
	}

	@Override
	protected void onDraw(Canvas canvas) {
		if (mBitmap == null) {
			return;
		}

		if (mFillColor != Color.TRANSPARENT) {
			canvas.drawCircle(getWidth() / 2.0f, getHeight() / 2.0f,
					mDrawableRadius, mFillPaint);
		}
		canvas.drawCircle(getWidth() / 2.0f, getHeight() / 2.0f,
				mDrawableRadius, mBitmapPaint);
		if (mBorderWidth != 0) {
			canvas.drawCircle(getWidth() / 2.0f, getHeight() / 2.0f,
					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 void setBorderColorResource(int borderColorRes) {
		setBorderColor(getContext().getResources().getColor(borderColorRes));
	}

	public int getFillColor() {
		return mFillColor;
	}

	public void setFillColor(int fillColor) {
		if (fillColor == mFillColor) {
			return;
		}

		mFillColor = fillColor;
		mFillPaint.setColor(fillColor);
		invalidate();
	}

	public void setFillColorResource(int fillColorRes) {
		setFillColor(getContext().getResources().getColor(fillColorRes));
	}

	public int getBorderWidth() {
		return mBorderWidth;
	}

	public void setBorderWidth(int borderWidth) {
		if (borderWidth == mBorderWidth) {
			return;
		}

		mBorderWidth = borderWidth;
		setup();
	}

	public boolean isBorderOverlay() {
		return mBorderOverlay;
	}

	public void setBorderOverlay(boolean borderOverlay) {
		if (borderOverlay == mBorderOverlay) {
			return;
		}

		mBorderOverlay = borderOverlay;
		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();
	}

	@Override
	public void setImageURI(Uri uri) {
		super.setImageURI(uri);
		mBitmap = uri != null ? getBitmapFromDrawable(getDrawable()) : null;
		setup();
	}

	/**
	 * 为圆形Iamge设置IamgeUrl
	 * 
	 * @param url 图片的url
	 */
	public void setImageURL(final String url) {

		final Handler handler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				super.handleMessage(msg);
				setImageBitmap(bitmap);
			}
		};

		/**
		 * 网络操作相关的子线程
		 */
		new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO
				// 在这里进行 http request.网络请求相关操作
				Message msg = new Message();
				bitmap = ImageLoader.getInstance().loadImageSync(url);
				handler.sendMessage(msg);
			}
		}).start();

	}

	@Override
	public void setColorFilter(ColorFilter cf) {
		if (cf == mColorFilter) {
			return;
		}

		mColorFilter = cf;
		mBitmapPaint.setColorFilter(mColorFilter);
		invalidate();
	}

	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 (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	private void setup() {
		if (!mReady) {
			mSetupPending = true;
			return;
		}

		if (getWidth() == 0 && getHeight() == 0) {
			return;
		}

		if (mBitmap == null) {
			invalidate();
			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);

		mFillPaint.setStyle(Paint.Style.FILL);
		mFillPaint.setAntiAlias(true);
		mFillPaint.setColor(mFillColor);

		mBitmapHeight = mBitmap.getHeight();
		mBitmapWidth = mBitmap.getWidth();

		mBorderRect.set(0, 0, getWidth(), getHeight());
		mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2.0f,
				(mBorderRect.width() - mBorderWidth) / 2.0f);

		mDrawableRect.set(mBorderRect);
		if (!mBorderOverlay) {
			mDrawableRect.inset(mBorderWidth, mBorderWidth);
		}
		mDrawableRadius = Math.min(mDrawableRect.height() / 2.0f,
				mDrawableRect.width() / 2.0f);

		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) + mDrawableRect.left,
				(int) (dy + 0.5f) + mDrawableRect.top);

		mBitmapShader.setLocalMatrix(mShaderMatrix);
	}

}

喜欢就点个赞吧微笑


CircleImageView实现图片的圆形遮罩效果(使用自定义ImageView实现) CircleImageView使用自定义ImageView实现图片的圆形遮罩效果,详细了解请移步http://blog.youkuaiyun.com/zxc514257857/article/details/63834235 立即下载

相关推荐

Android-使用clippath实现的CircleImageView没有Bitmap没有锯齿

使用clippath实现的CircleImageView,没有Bitmap,没有锯齿

android 自定义circleimageview,Android 自定义圆形头像CircleImageView支持加载网络图片的实现代码...

在Android开发中我们常常用到圆形的头像,如果每次加载之后再进行圆形裁剪特别麻烦。所以在这里写一个自定义圆形ImageView,直接去加载网络图片,这样的话就特别的方便。先上效果图主要的方法1.让自定义 CircleImageView 继承ImageView/*** 自定义圆形头像* Created by Dylan on 2015/11/26 0026.*/public class Circ...

weixin_33075245的博客 628

Android-Android圆形图片加载加载本地及网络图片

在项目中使用圆形的图片的需求还是蛮大的,所以封装一个圆形图片的控件,可以加载本地图片以及网络图片,此控件是继承自Imageview控件。

CircleImageView用法及源码解析(雷惊风)

首先这篇文章我们从以下四个方面进行一一讲解1.CircleImageView在AS中集成及用法;2.CircleImageView中定义的对外的方法;3.源码解析;4.用到的知识点的总计。希望通过本篇文章的学习,您会对自定义控件及自定义控件中用到的一些类有一定的了解,最后我会把我添加好详细注释的Demo下载地址附上,你也可以一边看我的Demo,一边看这篇文章,效果应该会更好,那么,我们这就开始吧!

刘永雷的专栏 1万+

Android 自定义圆形头像CircleImageView支持加载网络图片的实现代码

主要介绍了Android 自定义圆形头像CircleImageView支持加载网络图片的实现代码,非常不错具有参考借鉴价值,需要的朋友可以参考下

CST新手必看:共面波导色散曲线绘制全流程(附参数设置详解)

本文为CST新手提供了绘制共面波导色散曲线的完整流程与参数设置详解。从模型搭建、周期性边界条件设置,到本征模求解器配置和参数扫描技巧,逐步解析关键步骤,并分享后处理与结果验证方法,帮助用户高效完成仿真任务。

j0k1l2m3n的博客 422

android 设置头像(PictureSelector、CircleImageView等库结合极光IM服务)

android使用PictureSelector和CircleImageView等结合极光IM服务,实现头像的设置和获取(仅图库选取照片) 1.用到的依赖 implementation ('com.github.LuckSiege.PictureSelector:picture_library:v2.5.9')//图库选择 implementation ('de.hdodenhof:circleimageview:2.1.0')//放圆形头像的控件 implementation 'com.andro.

孤注一掷的博客 1015

2025小红书跳转卡片实战指南:从零搭建独立后台与自动化发卡系统

本文提供了一份2025年小红书跳转卡片的实战搭建指南,详细解析了独立后台系统的核心架构与自动化发卡流程。文章从零开始,手把手教你使用Node.js、Vue.js等技术栈构建包含后台管理、用户制卡中心与前端交互的完整系统,旨在帮助运营者实现合规引流,并掌握数据自主权与自动化运营能力。

weixin_29234423的博客 517

【Android自定义View实战】之自定义圆形头像CircleImageView支持加载网络图片

在Android开发中我们常常用到圆形的头像,如果每次加载之后再进行圆形裁剪特别麻烦。所以在这里写一个自定义圆形ImageView,直接去加载网络图片,这样的话就特别的方便。 先上效果图 主要的方法 1.让自定义 CircleImageView 继承ImageView /** * 自定义圆形头像 * Created by Dylan on 2015/11/26 0026.

DylanAndroid 6251

【PLC】三菱plc控件安装 component Movedata had the following error ... Error Number:-119

Windows 10 专业版/企业版本版本号:22H2操作系统内部版本:19045.3448。

少莫千华 8002

Coze工作流实战:Coze一键生成沉浸式历史故事视频

【coze工作流实战】一键生成火爆的沉浸式历史故事视频!短短3分钟,顶替你3天的工作量!

bickys的博客 1004

解决-Glide加载CircleImageView失败

在用Glide加载自定义的圆形图片时,显示的是占位图 - 加载图片的代码Glide.with(context) .apply(new RequestOptions().placeHolder(resId)) .transition(withCrossfade()) .load(url) .into(mCircleImageView) 产生原因 目前Glide不支

HuangLin的博客 1524

Android SDK安装教程(超详细),从零基础入门到精通,从这篇开始_android sdk下载安装

Android SDK安装教程(超详细),从零基础入门到精通,从这篇开始_android sdk下载安装

Jinmindong 5013

圆形图片CircleImageView(解决内存溢出)

一、前言项目已经做完了,目前测试那边还没有提交什么bug,所以目前对代码进行重构和优化。有一个很头疼的问题就是圆形图像引起GC内存溢出,logcat老打印:Grow heap (frag case) to 20.982MB for 1542416-byte allocation 和 GC_FOR_ALLOC freed 407K, 20% free 17919K/22332K, paused 16m

z240336124的专栏 5608

Lasso的原理及其与其他特征选择方法的比较进行阐述,然后讨论Lasso优点、缺点以及应用场景,最后给出了代码实例

在机器学习领域中,特征选择(feature selection)是指在模型训练前对数据集进行分析,选择其中有助于预测目标变量或影响模型性能的特征,去除不相关或冗余的特征,提升模型的泛化能力。而Lasso回归是一种很流行的用于特征选择的方法之一。Lasso回归(又称LASSO,least absolute shrinkage and selection operator)是一种线性模型中的特征选择方法。

AI天才研究院 3051

OmniDrive(3):逐行代码详解

模型效果: 端到端联合规划与推理 接下来,简单介绍下训练的配置 1.1 模型配置 模型基于sparse query based的3D Bev感知框架StreamPetr ,用query来编码动态目标(如车辆、行人)和静态地图元素(如车道线)。(1) tran、test和val数据配置 指定真值的文件路径: ann_file 指定输出处理的pipeline: 训练使用, test 和val使用 指定是否需要时序训练seq_mode (2)数据处理pipeline 自定义的Dataset 通过类实现,训

@bangbang的博客 719

[转]CircleImageView图片的显示

转载自:CircleImageView图片的显示 需添加两个依赖: implementation ‘de.hdodenhof:circleimageview:2.2.0’ implementation ‘com.github.bumptech.glide:glide:3.7.0’ 其中glide是用来动态加载图片的,如果不想动态加载,可不用 测试布局文件 <Button android:on...

skyang在路上 1172

SAP 生产订单工序删除状态撤回简介

2、我们在前台对于生产订单的状态一个是在生产订单抬头中的状态,另外一个是针对上面一直在测试的是工序的状态,这个两个状态是前台可见的状态,实际生产订单还有一个组件物料的状态,这个状态是不可见的一个状态。生产订单中的0010工序中对应的组件的栏位被标识,表示有物料分配到了0010的工序中,正常情况下0010的工序被分配了工序是不应该被删除的。将已领料的工序删除掉,导致异常的发生。当物料已领料会,用户仍然把已分配的物料的工序删除掉,导致后续业务操作过程中产生异常,如下图中所示,0010的工序被打上了删除标识。

我小时候很黑的博客 1940

CircleImageView解析

首先、它是继承自ImageView,给ImageView设置图片的方法就是setImageXXX,不管你是用JAVA代码设置,还是在XML里面用src,它最终还是调用JAVA的setImageXXX方法,在这些个方法的最后一定有一个invalidate的方法,让其调用onDraw。 CircleImageView的原理也是这样,声明一个mBitmap这个就是要带到CircleImageV

Android探索之路 1万+

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

( ImageView )——使用BitMap创建圆形的ImageView

图片路径 用户的使用的图片路径需要放到assets文件夹下面 并获取AssetManager对象(在获取图片资源时完成了该步骤) 获取资源文件中的图片资源 public Bitmap getBitMap(String path) { mAssetManager = this.getAssets(); InputStream in = null; try { ...

杜小叶的博客 558

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

android开源系列:CircleImageView自定义圆形控件的使用

1.自定义圆形控件github地址:https://github.com/hdodenhof/CircleImageView主要的类:package de.hdodenhof.circleimageview; import edu.njupt.zhb.main.R; import android.content.Context; import android.content.res.TypedAr

郑海波(莫川)的优快云博客 2万+

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

android circleimageview 导入到eclipse,使用开源库RoundedImageView 创建圆角ImageView以及引用时遇到的问题...

转载请标明出处:http://blog.youkuaiyun.com/u013015161/article/details/45939685自己业余开发的一个小程序,需要用圆角矩形的形式来展示图片。圆角矩形,很容易想到用shape样式来实现,但这次需要展示图片,同时图片还是需要可以动态更改的, 所以最好是通过一个圆角矩形的ImageView来实现。一时没什么思路,于是去GitHub上找到一个比较有名的开源库,...

weixin_28861381的博客 386

Android 开发入门实践(二):Kotlin 空安全,从可空类型到安全访问

延续 NewsApp 项目中的新闻标题练习,记录 Kotlin 安全调用。

Easyhood的博客 285
上一篇: json格式正确却无法转换成 JSONObject
下一篇: 解决Servlet中乱码问题
Shawn7788
博客等级 码龄12年 10粉丝 8原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值