Android自定义view实现圆形、圆角和椭圆图片(BitmapShader图形渲染)
一、前言
android实现圆角矩形,圆形或者椭圆等图形,一般主要是个自定义view
加上使用xfermode
实现的。实现圆角图片的方法其实不少,常见的就是利用xfermode
,shader
。本文直接继承imageview
,使用bitmapshader
方法来实现圆形、圆角和椭圆的绘制,等大家看我本文的方法后,其他的类似形状也就都能举一反三来来画出来了。
二、效果图:
三、bitmapshader简介
bitmapshader
是shader
的子类,可以通过paint.setshader(shader shader)
进行设置、
我们这里只关注bitmapshader
,构造方法:
mbitmapshader = new bitmapshader(bitmap, tilemode.clamp, tilemode.clamp);
参数1:bitmap
参数2,参数3:tilemode;
tilemode的取值有三种:
clamp 拉伸
repeat 重复
mirror 镜像
如果大家给电脑屏幕设置屏保的时候,如果图片太小,可以选择重复、拉伸、镜像;
重复:就是横向、纵向不断重复这个bitmap
镜像:横向不断翻转重复,纵向不断翻转重复;
拉伸:这个和电脑屏保的模式应该有些不同,这个拉伸的是图片最后的那一个像素;横向的最后一个横行像素,不断的重复,纵项的那一列像素,不断的重复;
public bitmapshader(bitmap bitmap,shader.tilemode tilex,shader.tilemode tiley)
调用这个方法来产生一个画有一个位图的渲染器(shader)。
bitmap 在渲染器内使用的位图
tilex the tiling mode for x to draw the bitmap in. 在位图上x方向花砖模式
tiley the tiling mode for y to draw the bitmap in. 在位图上y方向花砖模式
tilemode:(一共有三种)
clamp :如果渲染器超出原始边界范围,会复制范围内边缘染色。
repeat :横向和纵向的重复渲染器图片,平铺。
mirror :横向和纵向的重复渲染器图片,这个和repeat 重复方式不一样,他是以镜像方式平铺。
四、自定义圆形、圆角和椭圆的图片view的实现
1. 测量view的大小
@override protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { // todo auto-generated method stub super.onmeasure(widthmeasurespec, heightmeasurespec); // 如果是绘制圆形,则强制宽高大小一致 if (mtype == type_circle) { mwidth = math.min(getmeasuredwidth(), getmeasuredheight()); mradius = mwidth / 2; setmeasureddimension(mwidth, mwidth); } }
2、设置bitmapshader和画笔paint
/** * 设置bitmapshader */ private void setbitmapshader() { drawable drawable = getdrawable(); if (null == drawable) { return; } bitmap bitmap = drawabletobitmap(drawable); // 将bitmap作为着色器来创建一个bitmapshader mbitmapshader = new bitmapshader(bitmap, tilemode.clamp, tilemode.clamp); float scale = 1.0f; if (mtype == type_circle) { // 拿到bitmap宽或高的小值 int bsize = math.min(bitmap.getwidth(), bitmap.getheight()); scale = mwidth * 1.0f / bsize; } else if (mtype == type_round || mtype == type_oval) { // 如果图片的宽或者高与view的宽高不匹配,计算出需要缩放的比例;缩放后的图片的宽高,一定要大于我们view的宽高;所以我们这里取大值; scale = math.max(getwidth() * 1.0f / bitmap.getwidth(), getheight() * 1.0f / bitmap.getheight()); } // shader的变换矩阵,我们这里主要用于放大或者缩小 mmatrix.setscale(scale, scale); // 设置变换矩阵 mbitmapshader.setlocalmatrix(mmatrix); mpaint.setshader(mbitmapshader); }
3.最后就是绘制出来圆角、圆形和椭圆的图片,肯定在ondraw
里面啦,根本原理就是使用了上面mbitmapshader
渲染的画笔来绘制
@override protected void ondraw(canvas canvas) { if (null == getdrawable()) { return; } setbitmapshader(); if (mtype == type_circle) { canvas.drawcircle(mradius, mradius, mradius, mpaint); } else if (mtype == type_round) { mpaint.setcolor(color.red); canvas.drawroundrect(mrect, mroundradius, mroundradius, mpaint); }else if(mtype == type_oval){ canvas.drawoval(mrect, mpaint); } }
五、视图布局实现
这个很简单,就是3个自定义的view
:
<scrollview xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".mainactivity" > <linearlayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:layout_margintop="5dp" android:layout_marginbottom="25dp" android:orientation="vertical" > <com.czm.viewdrawtest.xcroundandovalimageview android:id="@+id/cicleimageview" android:layout_width="200dp" android:layout_height="200dp" android:src="@drawable/img1" /> <com.czm.viewdrawtest.xcroundandovalimageview android:id="@+id/roundrectimageview" android:layout_width="200dp" android:layout_height="240dp" android:layout_margintop="5dp" android:src="@drawable/img2" /> <com.czm.viewdrawtest.xcroundandovalimageview android:id="@+id/ovalimageview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margintop="5dp" android:src="@drawable/img3" /> </linearlayout> </scrollview>
六、使用和测试自定义view
上面直接绘制的自定义view
写完了,下面就是使用这个view
了,使用方法和普通的imageview
一样,当作普通控件使用即可。
package com.czm.viewdrawtest; import android.app.activity; import android.os.bundle; import android.view.window; import android.view.windowmanager; /** * 使用自定义imageview * @author caizhiming * */ public class mainactivity extends activity { private xcroundandovalimageview circleimageview;//圆形图片 private xcroundandovalimageview roundrectimageview;//圆角矩形图片 private xcroundandovalimageview ovalimageview;//椭圆图片 @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); //设置无标题 requestwindowfeature(window.feature_no_title); //设置全屏 getwindow().setflags(windowmanager.layoutparams.flag_fullscreen, windowmanager.layoutparams.flag_fullscreen); setcontentview(r.layout.activity_main); initviews(); } /** * 初始化views */ private void initviews(){ circleimageview = (xcroundandovalimageview)findviewbyid(r.id.cicleimageview); roundrectimageview = (xcroundandovalimageview)findviewbyid(r.id.roundrectimageview); ovalimageview = (xcroundandovalimageview)findviewbyid(r.id.ovalimageview); roundrectimageview.settype(xcroundandovalimageview.type_round); roundrectimageview.setroundradius(100); ovalimageview.settype(xcroundandovalimageview.type_oval); ovalimageview.setroundradius(50); } }
七、总结
以上就是本文的全部内容,希望这篇文章的内容对大家开发android能有所帮助。