图片亲爱的原型型

18603人阅读
转载请标明出处:http://blog.csdn.net/lmj/article/details/本来想在网上找个圆角的例子看一看,不尽人意啊,基本都是官方的Demo的那张原理图,稍后会贴出。于是自己自定义了个View,实现图片的圆角以及圆形效果。效果图:第一个是原图,第二个是圆形效果,第三第四设置了不同的圆角大小。准备改变一个博客的风格,首先给大家讲一下原理,让大家明白了,然后再贴代码,不然可以直接看那么长的代码也比较痛苦,核心代码其实就那么几行:核心代码分析:/**
* 根据原图和变长绘制圆形图片
* @param source
* @param min
private Bitmap createCircleImage(Bitmap source, int min)
final Paint paint = new Paint();
paint.setAntiAlias(true);
Bitmap target = Bitmap.createBitmap(min, min, Config.ARGB_8888);
* 产生一个同样大小的画布
Canvas canvas = new Canvas(target);
* 首先绘制圆形
canvas.drawCircle(min / 2, min / 2, min / 2, paint);
* 使用SRC_IN
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
* 绘制图片
canvas.drawBitmap(source, 0, 0, paint);
}其实主要靠:paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));这行代码,为什么呢,我给大家解释下,SRC_IN这种模式,两个绘制的效果叠加后取交集展现后图,怎么说呢,咱们第一个绘制的是个圆形,第二个绘制的是个Bitmap,于是交集为圆形,展现的是BItmap,就实现了圆形图片效果。圆角,其实就是先绘制圆角矩形,是不是很简单,以后别人再说实现圆角,你就把这一行代码给他就行了。从Android的示例中,给大家证明一下:下面有一张PorterDuff.Mode的16中效果图,咱们的只是其一:源码咱们只关心谁先谁后绘制的:
canvas.translate(x, y);
canvas.drawBitmap(mDstB, 0, 0, paint);
paint.setXfermode(sModes[i]);
canvas.drawBitmap(mSrcB, 0, 0, paint);
paint.setXfermode(null);
canvas.restoreToCount(sc);可以看出先绘制的Dst,再绘制的Src,最后的展示是SrcIn那个图:显示的区域是二者交集,展示的是Src(后者)。和咱们前面结论一致。效果16种,大家可以自由组合展示不同的效果。好了,原理和核心代码解释完成。下面开始写自定义View。1、自定义属性:&?xml version=&1.0& encoding=&utf-8&?&
&resources&
&attr name=&borderRadius& format=&dimension& /&
&attr name=&type&&
&enum name=&circle& value=&0& /&
&enum name=&round& value=&1& /&
&attr name=&src& format=&reference&&&/attr&
&declare-styleable name=&CustomImageView&&
&attr name=&borderRadius& /&
&attr name=&type& /&
&attr name=&src& /&
&/declare-styleable&
&/resources&2、构造中获取自定义的属性: /**
* TYPE_CIRCLE / TYPE_ROUND
private static final int TYPE_CIRCLE = 0;
private static final int TYPE_ROUND = 1;
private Bitmap mS
* 圆角的大小
private int mR
* 控件的宽度
private int mW
* 控件的高度
private int mH
public CustomImageView(Context context, AttributeSet attrs)
this(context, attrs, 0);
public CustomImageView(Context context)
this(context, null);
* 初始化一些自定义的参数
* @param context
* @param attrs
* @param defStyle
public CustomImageView(Context context, AttributeSet attrs, int defStyle)
super(context, attrs, defStyle);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomImageView, defStyle, 0);
int n = a.getIndexCount();
for (int i = 0; i & i++)
int attr = a.getIndex(i);
switch (attr)
case R.styleable.CustomImageView_src:
mSrc = BitmapFactory.decodeResource(getResources(), a.getResourceId(attr, 0));
case R.styleable.CustomImageView_type:
type = a.getInt(attr, 0);// 默认为Circle
case R.styleable.CustomImageView_borderRadius:
mRadius= a.getDimensionPixelSize(attr, (int) TypedValue.PLEX_UNIT_DIP, 10f,
getResources().getDisplayMetrics()));// 默认为10DP
a.recycle();
3、onMeasure中获取控件宽高:/**
* 计算控件的高度和宽度
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
* 设置宽度
int specMode = MeasureSpec.getMode(widthMeasureSpec);
int specSize = MeasureSpec.getSize(widthMeasureSpec);
if (specMode == MeasureSpec.EXACTLY)// match_parent , accurate
mWidth = specS
// 由图片决定的宽
int desireByImg = getPaddingLeft() + getPaddingRight()
+ mSrc.getWidth();
if (specMode == MeasureSpec.AT_MOST)// wrap_content
mWidth = Math.min(desireByImg, specSize);
mWidth = desireByI
* 设置高度
specMode = MeasureSpec.getMode(heightMeasureSpec);
specSize = MeasureSpec.getSize(heightMeasureSpec);
if (specMode == MeasureSpec.EXACTLY)// match_parent , accurate
mHeight = specS
int desire = getPaddingTop() + getPaddingBottom()
+ mSrc.getHeight();
if (specMode == MeasureSpec.AT_MOST)// wrap_content
mHeight = Math.min(desire, specSize);
setMeasuredDimension(mWidth, mHeight);
}4、根据Type绘制:/**
protected void onDraw(Canvas canvas)
switch (type)
// 如果是TYPE_CIRCLE绘制圆形
case TYPE_CIRCLE:
int min = Math.min(mWidth, mHeight);
* 长度如果不一致,按小的值进行压缩
mSrc = Bitmap.createScaledBitmap(mSrc, min, min, false);
canvas.drawBitmap(createCircleImage(mSrc, min), 0, 0, null);
case TYPE_ROUND:
canvas.drawBitmap(createRoundConerImage(mSrc), 0, 0, null);
* 根据原图和变长绘制圆形图片
* @param source
* @param min
private Bitmap createCircleImage(Bitmap source, int min)
final Paint paint = new Paint();
paint.setAntiAlias(true);
Bitmap target = Bitmap.createBitmap(min, min, Config.ARGB_8888);
* 产生一个同样大小的画布
Canvas canvas = new Canvas(target);
* 首先绘制圆形
canvas.drawCircle(min / 2, min / 2, min / 2, paint);
* 使用SRC_IN,参考上面的说明
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
* 绘制图片
canvas.drawBitmap(source, 0, 0, paint);
* 根据原图添加圆角
* @param source
private Bitmap createRoundConerImage(Bitmap source)
final Paint paint = new Paint();
paint.setAntiAlias(true);
Bitmap target = Bitmap.createBitmap(mWidth, mHeight, Config.ARGB_8888);
Canvas canvas = new Canvas(target);
RectF rect = new RectF(0, 0, source.getWidth(), source.getHeight());
canvas.drawRoundRect(rect, mRadius, mRadius, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(source, 0, 0, paint);
}好了,我就不解析代码了,自定义View这是第五篇了,,,,写得好恶心,,,,各位赞一个或者留个言,算是对我的支持~=========================================简单修复了一下,在ScrollView以及AdapterView中的headview的显示异常的bug============修复后代码下载:相关博文,同时也推荐使用:
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:846255次
积分:14109
积分:14109
排名:第272名
原创:142篇
评论:2747条
如果你不喜欢枯燥的文本,请猛戳,期待您的支持:
长期为您推荐优秀博文、开源项目、视频等,进入还有好玩的等着你,欢迎扫一扫。
一群:【已满】
请勿重复加群,Thx
文章:11篇
阅读:28621
文章:10篇
阅读:15343
文章:67篇
阅读:540596
(3)(6)(7)(6)(7)(11)(10)(23)(17)(18)(39)(1)(1)翻页快捷键:←|→
最新游戏专题
最新热点资讯
单机下载排行该商品图片为网友上传的晒单图片,仅供参考,因购买时间或批次不同,实际购买的商品可能与此图片不一致。
正在加载中...
京品评分:下次自动登录
合作网站账户登录:
您现在的位置:
《功夫少林寺》图片原型欣赏
  由著名漫画家蔡志忠编剧导演的动画电影《》在河南嵩山少林寺启动制作,同时,少林寺也授权蔡志忠《功夫少林寺》游戏版权。对于3D手游《功夫少林寺》,官方透露的消息却不多,只宣称官方手游将与电影同步上市。小编猜测该手游的风格也是离不开中国传统文化跟中国水墨风格基调。
日期名称号
热门网络游戏排行
热门单机游戏排行
京ICP备号-1 京公网安备 86}

我要回帖

更多关于 亲爱的电影原型 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信