Android 圆角的效果实现
Android 自定义ImageView实现圆角图片
昨天给学生布置作业,写微信首页,也就是聊天的界面,listView里的item中联系人的头像是圆角的,图形界面如下:
那么我就仔细研究了圆角的具体实现。
那么首先,我想到了第一种实现方案:
1、就是给ImageView定义shape.xml文件,然后用src指定组件背景。那么想到这个方案的时候,我首先了解了一下ImageView的src和background属性。
background会根据ImageView组件给定的长宽进行拉伸,而src就存放的是原图的大小,不会进行拉伸 。src是图片内容(前景),bg是背景,可以同时使用。
这里我一看到可以同时使用,我瞬间就感觉哎,有门,那我就试了一下:
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@drawable/shape"
android:src="@mipmap/img_0326" />
这里shape.xml文件定义如下:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/colorhuise"/>
<corners android:radius="20dp"/>
</shape>
但是实现效果并不理想:方方正正,有棱有角的
我又自己测试了一下,把background改成图片,实现效果如下:
这是一张狗头和微信朋友圈的完美结合......哈哈,闲话少说那么很明显这里得出的结论是如果都设置背景图片的话可以一起使用,但是如果背景定义形状的时候就不起作用了。那么这种方法就不可行了,我们来尝试下一种方法:
2、自定义ImageView实现圆角图片:
这里我们自定义一个ImageView,代码如下:
public class RoundImageView extends ImageView {
/**
* 图片的类型,圆形or圆角
*/
private int type;
public static final int TYPE_CIRCLE = 0;
public static final int TYPE_ROUND = 1;
/**
* 圆角大小的默认值
*/
private static final int BODER_RADIUS_DEFAULT = 10;
/**
* 圆角的大小
*/
private int mBorderRadius;
/**
* 绘图的Paint
*/
private Paint mBitmapPaint;
/**
* 圆角的半径
*/
private int mRadius;
/**
* 3x3 矩阵,主要用于缩小放大
*/
private Matrix mMatrix;
/**
* 渲染图像,使用图像为绘制图形着色
*/
private BitmapShader mBitmapShader;
/**
* view的宽度
*/
private int mWidth;
private RectF mRoundRect;
public RoundImageView(Context context, AttributeSet attrs) {
super(context, attrs);
mMatrix = new Matrix();
mBitmapPaint = new Paint();
mBitmapPaint.setAntiAlias(true);
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.RoundImageView);
mBorderRadius = a.getDimensionPixelSize(
R.styleable.RoundImageView_borderRadius, (int) TypedValue
.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
BODER_RADIUS_DEFAULT, getResources()
.getDisplayMetrics()));// 默认为10dp
type = a.getInt(R.styleable.RoundImageView_type, TYPE_CIRCLE);// 默认为Circle
a.recycle();
}
public RoundImageView(Context context) {
this(context, null);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
/ **
* 如果类型是圆形,则强制改变view的宽高一致,以小值为准
*/
if (type == TYPE_CIRCLE) {
mWidth = Math.min(getMeasuredWidth(), getMeasuredHeight());
mRadius = mWidth / 2;
setMeasuredDimension(mWidth, mWidth);
}
}
/**
* 初始化BitmapShader
*/
private void setUpShader() {
Drawable drawable = getDrawable();
if (drawable == null) {
return;
}
Bitmap bmp = drawableToBitamp(drawable);
// 将bmp作为着色器,就是在指定区域内绘制bmp
mBitmapShader = new BitmapShader(bmp, TileMode.CLAMP, TileMode.CLAMP);
float scale = 1.0f;
if (type == TYPE_CIRCLE) {
// 拿到bitmap宽或高的小值
int bSize = Math.min(bmp.getWidth(), bmp.getHeight());
scale = mWidth * 1.0f / bSize;
} else if (type == TYPE_ROUND) {
Log.e("TAG",
"b'w = " + bmp.getWidth() + " , " + "b'h = "
+ bmp.getHeight());
if (!(bmp.getWidth() == getWidth() && bmp.getHeight() == getHeight())) {
// 如果图片的宽或者高与view的宽高不匹配,计算出需要缩放的比例;缩放后的图片的宽高,一定要大于我们view的宽高;所以我们这里取大值;
scale = Math.max(getWidth() * 1.0f / bmp.getWidth(),
getHeight() * 1.0f / bmp.getHeight());
}
}
// shader的变换矩阵,我们这里主要用于放大或者缩小
mMatrix.setScale(scale, scale);
// 设置变换矩阵
mBitmapShader.setLocalMatrix(mMatrix);
// 设置shader
mBitmapPaint.setShader(mBitmapShader);
}
@Override
protected void onDraw(Canvas canvas) {
Log.e("TAG", "onDraw");
if (getDrawable() == null) {
return;
}
setUpShader();
if (type == TYPE_ROUND) {
canvas.drawRoundRect(mRoundRect, mBorderRadius, mBorderRadius,
mBitmapPaint);
} else {
canvas.drawCircle(mRadius, mRadius, mRadius, mBitmapPaint);
// drawSomeThing(canvas);
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// 圆角图片的范围
if (type == TYPE_ROUND)
mRoundRect = new RectF(0, 0, w, h);
}
/**
* drawable转bitmap
*
* @param drawable
* @return
*/
private Bitmap drawableToBitamp(Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bd = (BitmapDrawable) drawable;
return bd.getBitmap();
}
int w = drawable.getIntrinsicWidth();
int h = drawable.getIntrinsicHeight();
Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, w, h);
drawable.draw(canvas);
return bitmap;
}
private static final String STATE_INSTANCE = "state_instance";
private static final String STATE_TYPE = "state_type";
private static final String STATE_BORDER_RADIUS = "state_border_radius";
@Override
protected Parcelable onSaveInstanceState() {
Bundle bundle = new Bundle();
bundle.putParcelable(STATE_INSTANCE, super.onSaveInstanceState());
bundle.putInt(STATE_TYPE, type);
bundle.putInt(STATE_BORDER_RADIUS, mBorderRadius);
return bundle;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state instanceof Bundle) {
Bundle bundle = (Bundle) state;
super.onRestoreInstanceState(((Bundle) state)
.getParcelable(STATE_INSTANCE));
this.type = bundle.getInt(STATE_TYPE);
this.mBorderRadius = bundle.getInt(STATE_BORDER_RADIUS);
} else {
super.onRestoreInstanceState(state);
}
}
public void setBorderRadius(int borderRadius) {
int pxVal = dp2px(borderRadius);
if (this.mBorderRadius != pxVal) {
this.mBorderRadius = pxVal;
invalidate();
}
}
public void setType(int type) {
if (this.type != type) {
this.type = type;
if (this.type != TYPE_ROUND && this.type != TYPE_CIRCLE) {
this.type = TYPE_CIRCLE;
}
requestLayout();
}
}
public int dp2px(int dpVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dpVal, getResources().getDisplayMetrics());
}
}
那么使用的时候,也比较方便
<com.zhy.view.RoundImageView
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_margin="10dp"
android:scaleType="centerCrop"
android:src="@drawable/img"
map:borderRadius="60dp"
map:type="round" >
</com.zhy.view.RoundImageView>
这里实现效果是圆角的:
这里给大家讲几个其他的用法:根据上面type的类型为circle为第一个圆形效果,为round时实现第二个效果,通过borderRadius属性控制边角的弧度。
3、讲完了自定义,我们再给大家分享一个gitHub上的经典:
https://github.com/siyamed/android-shape-imageview
使用方法:
1、添加依赖:
在build.gradle(Module:app)下添加:
compile 'com.github.siyamed:android-shape-imageview:0.9.+@aar'
这里要注意使用的话最小版本要改成9或者以上
2、添加完成之后从新build一下,引用资源
3、布局文件中直接使用:
<com.github.siyamed.shapeimageview.RoundedImageView
android:layout_width="300dp"
android:layout_height="300dp"
android:src="@drawable/qiqiu"
app:siRadius="20dp"/>
这里的siRadius就相当于shape.xml里面的radius属性,即控制圆角弧度。这里使用的时候引用app的资源会爆红,解决方法是在最外层布局里面给他添加上引用:
xmlns:app="http://schemas.android.com/apk/res-auto"
这个超简单的,效果就实现啦:
这里我们只给大家演示了矩形圆角,那其他的效果大家可以直接去gitHub上面去调用具体实现。
转载于:https://www.cnblogs.com/bobohaohao/p/5633042.html
Android 圆角的效果实现相关推荐
- android 图片圆角 遮罩_Android 自定义View练手Demo(一)实现圆角遮罩效果
Android 自定义View系列文章 Android自定义View实现圆角遮罩效果 一图胜千言,有一个遮罩就会凸显出重点区域 1-1.jpg 本文通过两种方式来实现这种效果,来达到自定义View练手 ...
- android java 圆角_Android自定义View实现带4圆角或者2圆角的效果
1 问题 实现任意view经过自定义带4圆角或者2圆角的效果 2 原理 1) 实现view 4圆角 我们只需要把左边的图嵌入到右边里面去,最终显示左边的图就行. 2) 实现view上2圆角 我们只需要 ...
- Android之自定义View实现带4圆角或者2圆角的效果
1 问题 实现任意view经过自定义带4圆角或者2圆角的效果 2 原理 1) 实现view 4圆角 我们只需要把左边的图嵌入到右边里面去,最终显示左边的图就行. 2) 实现view上2圆角 我们只需要 ...
- android 两边圆角,Android自定义View实现带4圆角或者2圆角的效果
1 问题 实现任意view经过自定义带4圆角或者2圆角的效果 2 原理 1) 实现view 4圆角 我们只需要把左边的图嵌入到右边里面去,最终显示左边的图就行. 2) 实现view上2圆角 我们只需要 ...
- android 圆角效果
android 圆角效果 最近做一个效果,要一个上边两个角为圆角,下面两个角为直角的四边形白色背景: 如下图: 这里用到了shape属性中的corners 属性, api原文中是这样: <cor ...
- android 圆角边框边框渐变,Android中用shape做渐变,边框,圆角等效果
以前没接触到shape的时候,做圆角,渐变等效果都是依赖图片效果:如果对PS不熟悉,光是做图就要花去大把时间. 废话不讲了,把总结的内容记录下来,俺们不是在写博客,算是做个云笔记吧. shape用法与 ...
- android圆角布局阴影,Android 布局阴影实现
最近项目要求,ui有很多有关于阴影的设计要求,网上找了些实现方式,但都不是很理想.现在闲下来了,就寻思着自己写个阴影布局耍耍,以备后用.先说道说道我找到的几种阴影实现方式: 系统阴影 Andorid ...
- android 圆角边框有灰,Android开发笔记——圆角和边框们
在做Android界面开发时,我们往往希望它尽可能优美,尽可能显得专业.于是你看了看其他应用,哇,好多边框和圆角啊.你是不是也想给自己的应用加上边框和圆角效果?呃--那怎么做呢?如果你是从web前端跑 ...
- Android 圆角圆形ImageView(超简单实现)
前言:今天偶然看到我之前写过的一篇博客 Android项目中遇到的坑之(Android圆角圆形图 一),我在想,这不就是在模仿ImageView么,我为什么要模仿,直接拿来用不是更好么?我能直接在Im ...
- android 下拉窗帘,Android 窗帘(Curtain)效果二之波浪式动态扭曲效果
上一篇文章已经实现了如何把一张图片扭曲成波浪效果,那么这一篇文章我们介绍如何动态调整系数,去改变波浪图片的皱褶成度.我们自一次观察下图morning routine的效果: 仔细观察我们发现,当往右滑 ...
最新文章
- 数据结构-顺序查找的二分查找法(折半查找)
- Excel制作带勾的方框
- git安装,windows下git bash默认目录更改
- UVA - 725 Division-sprintf的妙用
- IPv6时代已来:双十一中的IPv6大规模应用实践
- 对Go 1.16 io/fs设计的第一感觉:得劲儿!
- PIE SDK专题制图切换模板
- 微信小程序获取收货地址
- 贴吧云签到php源码,求助帮忙把PHP的贴吧签到代码转换到云函数下
- 吃豆豆--Java小游戏
- PCB封装欣赏了解之旅(上篇)—— 常用元器件
- Xshell——连接服务器
- 圣邦微电子2023校招笔试
- Android入门:Layout
- python读取txt转为csv
- oracle的高级特性,Oracle SQL Developer 的高级特性
- 一分钟教你如何将Word生成目录,就是这么简单
- 小E开发板wifi音箱一实现PC通过wifi传数据到开发板进行播放
- linux游戏环境安装失败,安装配置Lutris,一款Linux下多平台游戏管家
- 电信天翼云NB-IOT平台数据接入
热门文章
- .NET Oject And Json
- 09年让你笑到肚疼的签名
- win10+anaconda3+python3.7+pytorch-cpu安装
- EMNLP'21 | Dialogue System 对话系统
- 【征收SCI稿件】厦门大学信息学院主办!通讯技术与信息科技征稿中!
- 谷歌最新模型pQRNN:效果接近BERT,参数量缩小300倍
- 【推荐系统】推荐系统中的图网络模型
- stats—stats.probplot绘制数据与正态分布分位数的拟合图
- 统计学习方法读书笔记10-决策树
- bug1-tensorflow中自定义模型的bug-input_signature