下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、自定义view实现圆角图片前两天想实现一个圆角图片的效果,通过网络搜索后找到一些答案。这里自己再记录一下,加深一下自己的认识和知识理解。实现圆角图片的思路是自定义一个ImageView,然后通过Ondraw()重绘的功能,将drawable和一个圆形进行重叠绘制,这样就可以达到圆角的效果了。下面开始具体实现圆角图片的过程。第一步:写自定义属性文件首先我们需要定义一个属性。在values目录下面新建一个xml文件,这个文件用来自定义一些属性,这样我们就可以写出自己的控件了。12345678910我来简单解释一下,declare-styleable这个标签就是用来自定义属性的,attr标签用来定义
2、具体的属性,format可以指定很多种格式,具体有哪些属性,这里不做过多介绍了,请看博客中的介绍://mayingcai1987/article/details/6216655。在本例子中dimension表示尺寸的意思,这个应该在平常的开发中也用到。同时还有一个enum的枚举类型,我们之前在用系统控件的时候,比如android:orientation=vertical就是比较典型的枚举类型,只不过在本例中我们自己实现了这个枚举类型。定义好这个之后,我们就可以开始写我们的自定义view的代码了。最后注意的一点,这里的这个xml的名字可以随便命名(不过最好命名的比较有意
3、义),android系统会自动找到的。第二步,自定义View这一步是本文中最重要的一步,也是实现自定义view的核心。那么我们从目的出发来探讨实现圆角image的方式。那么我们的目的是将图片变圆,在这里一般人可能有想到两种方式将图片变圆 1.把本来图片修改为圆形,其他地方都是透明2.只是让显示的时候,动态的裁剪到一些部分,然后让图片变圆。这两种方法的优劣我想大家一眼就能看明白。直接修改图片,带来的后果是,我如果换了一种方式了,不再是圆角,而是星型,那么我们的图片已经毁掉了,没办法在重用了。而第二种方式就可以,无论我们换什么样的表现方式,我们是需要换一种裁剪的算法,就可以实现不同的形状的图片了,
4、那么很显然,第二种方法是以不变应万变的。那么现在,我们选定了第二种方式,那怎么实现呢?有人说我们自己写一个类,直接继承自view,然后所有的绘图和大小的计算我们都自己来搞,这样行吗?当然可行,但是我们可能是在重复造轮子,因为我们已经有了一个ImageView,而且它里面给我们做了很多关于图片的操作,我们何不继承自ImageView,然后做少量的工作,就可以实现圆角效果呢。方案确定,好,那我们就开始实现自己的类。1public class RoundImageView extends ImageView 我们定义一个RoundImageView 继承自ImageView12private int
5、 mBorderRadius;private int mType;然后两个成员变量,分别对应于自定义属性文件中的BorderRadius和RoundType。接下来我们重写构造函数12345678910111213public RoundImageView(Context context, AttributeSet attrs) super(context, attrs);mPaint = new Paint(); mPaint.setAntiAlias(true);TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.
6、RoundImageAttrs);mBorderRadius = a.getDimensionPixelSize(R.styleable.RoundImageAttrs_BorderRadius,(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getResources().getDisplayMetrics();mType = a.getInt(R.styleable.RoundImageAttrs_RoundType,0);a.recycle();Log.i(Log,mBorderRadius:+mBorderR
7、adius+type:+mType);首先是mPaint的初始化,这是一个画刷,用来画图形的,后面会说。接下来是最为关键的代码,context.obtainStyledAttributes(attrs,R.styleable.RoundImageAttrs),这句代码用来获取控件上的自定义属性。然后下面两句12mBorderRadius = a.getDimensionPixelSize(R.styleable.RoundImageAttrs_BorderRadius,(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10,
8、 getResources().getDisplayMetrics();mType = a.getInt(R.styleable.RoundImageAttrs_RoundType,0);分别获取这两个属性的值,第一个比较复杂,涉及到默认值单位的转换,(这里10的代表默认值)第二个就是获取RoundImageAttrs_RoundType,获取完毕后,记得一定要调用a.recycle();对资源进行释放。以便后面的其他代码可以访问这些属性资源。(理解的不透彻,但记住释放就ok)到现在为止我们完成了万里长征第一步,获取到了我们自定义控件的属性了。接下来就是我们的重头戏,重绘图片。下面我们重写了O
9、nDraw函数1234567891011121314151617181920212223242526272829303132333435Overrideprotected void onDraw(Canvas canvas) /super.onDraw(canvas);Bitmap bitmap = mWeakBitmap = nullnull:mWeakBitmap.get();if(bitmap = null | bitmap.isRecycled() Drawable drable = getDrawable();int width = drable.getIntrinsicWidth(
10、);int height = drable.getIntrinsicHeight();if(drable!=null)bitmap = Bitmap.createBitmap(getWidth(),getHeight(),Config.ARGB_8888);Canvas dcanvas = new Canvas(bitmap);drable.draw(dcanvas);if(mMashBitmap = null | mMashBitmap.isRecycled()mMashBitmap = getShapeBitmap();mPaint.reset();mPaint.setFilterBitm
11、ap(false);mPaint.setXfermode(mXfermode);dcanvas.drawBitmap(mMashBitmap, 0,0, mPaint);mPaint.setXfermode(null);canvas.drawBitmap(bitmap, 0,0, null);mWeakBitmap = new WeakReference(bitmap); elsemPaint.setXfermode(null);canvas.drawBitmap(bitmap, 0,0, null);return;上面的代码可能第一次看比较迷惑,各种paint还有canvas,drawabl
12、e,各种区分不清。下面我结合代码都说说。1Bitmap bitmap = mWeakBitmap = nullnull:mWeakBitmap.get();这句话是从一个弱引用中取得Bitmap图像,我们在成功创建圆形图像后,会保存起来,以供后面刷新使用。接下来我们判断bitmap,如果为空说明还没有创建过。接下来我们通过getDrawable();获取当前ImageView的drawable,里面包含了原本的图像。下面我们创建了一个临时的Bitmap对象,这个对象将保存经过我们处理之后的图像bitmap = Bitmap.createBitmap(getWidth(),getHeight()
13、,Config.ARGB_8888); 然后我们创建一个Canvas dcanvas = new Canvas(bitmap); drable.draw(dcanvas); 通过drawable的draw方法将原来ImageView的图像绘制到dcanvas上(其实也是画到bitmap上)。接下来我们获取图形(这里是圆形,后面大家可以自己定义形状)mMashBitmap = getShapeBitmap();(这个函数我们后面介绍),然后我们设置了paint的属性 private Xfermode mXfermode = new PorterDuffXfermode(Mode.DST_IN);
14、 mPaint.setXfermode(mXfermode);这个mXfermode代表的意思是,当用paint画图时,新绘制的图像与原图像的关系。给大家一张图,就很容易理解各种绘制方式了。1,在本例子中用的就是DST_IN,想必这张图一看就明白。paint配置完后,我们就开始将新的形状绘制到原来的图像上1dcanvas.drawBitmap(mMashBitmap, 0,0, mPaint); 此时,bitmap中保存的就是叠加之后的图片了,也就是我们最终需要的圆角图片了。最后我们将这个bitmap绘制到OnDraw函数给我们传递进来的canvas上,所有工作就基本做完了。canvas.dr
15、awBitmap(bitmap, 0,0, null);最后将绘制好的图片保存起来。mWeakBitmap = new WeakReference(bitmap);下一次执行ondraw 的时候,我们就直接用保存好的bitmap进行绘制了,也就是我们代码中else的部分。最艰难的部分说完了,哈哈,如果不理解还是得多看几遍。接下来的工作就轻松了很多,对了,我们还没有实现之前那个绘制形状的函数呢。我们来绘制把。很容易的。1234567891011121314private Bitmap getShapeBitmap()Bitmap bit = Bitmap.createBitmap(getWidt
16、h(),getHeight(),Config.ARGB_8888);Canvas can = new Canvas(bit);Paint pa = new Paint(Paint.ANTI_ALIAS_FLAG);pa.setColor(Color.BLACK);if(mType = 0)can.drawCircle(getWidth()/2, getHeight()/2, mBorderRadius, pa);return bit;看看上面的代码,是不是很熟悉,我们之前已经接触过基本的画图方法了。想必,不用解释了,一眼都能看明白。这里我只实现了画圆的,大家可以各自发挥想想,画出各种各样的形状,哈哈,是不是很容易,我们自己实现了圆角图像,同时对于android自定义view的绘制也有了大致了解。对了,这里面还有一个问题,如果用户想动态修改图片怎么办,我们在内存里面保存了一个旧的图片,该怎么更新呢。其实好办,我们只需要做下面的操作就行123
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 26年银发鼻饲护理实操考核标准课件
- 医学26年:困有所助要点解读 查房课件
- 26年基因检测卡脖子技术突破要点
- 20XX中学教师师德演讲稿:用爱铸就希望
- 淘宝代运营职业规划指南
- 手抄报设计模板
- 产品经理就业指导计划
- 预防口腔宣教
- 煤炭销售协议2026年意向版
- 西式厨师中级试卷及答案
- 四级手术术前多学科讨论制度(2025年)
- 2025年贵州贵阳事业单位招聘考试卫生类医学检验专业知识试卷
- 2025年大学《日语》专业题库- 跨文化交际与日语表达
- 2025年一建实务真题试卷及答案
- 2025年中国饭铲数据监测报告
- 八年级英语语法集中突破
- 医学三新项目汇报
- 成都新都投资集团有限公司招聘笔试题库2025
- 加强农村三资管理课件
- 公路工程2018预算定额释义手册
- 自愈合混凝土裂缝修复技术专题报告
评论
0/150
提交评论