Android圆角图片和圆形图片实现总结

本文总结了Android中实现圆角和圆形图片的多种方法,包括图层叠加、重新绘制(BitmapShader、Xfermode、RoundedBitmapDrawable)、CardView控件以及圆形图片的裁剪技巧。推荐使用BitmapShader实现圆角图片,因为它灵活性高,可以实现更多定制效果。CardView在5.0以上系统能轻松实现圆角,但不支持5.0以下系统。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载注明出处:http://blog.youkuaiyun.com/xiaohanluo/article/details/52945791

1. 概述

       Android研发中经常会遇见圆角或者圆形图片的展示,但是系统中ImageView并不能直接支持,需要我们自己做一些处理,来实现圆角图片或者圆形图片,自己最近对这块的实现做了一下总结,看以下几种实现方法。

  • 图层叠加,上层覆盖一层蒙版,遮挡图片,让图片展示出圆角或者圆形效果
  • 重新绘制
    • BitmapShader
    • Xfermode
    • RoundedBitmapDrawable
  • CardView,使用官方控件,自动裁剪,达到圆角或者圆形效果。(5.0以上系统)

       第一种方法,很傻,不太优雅,不推荐这种方法,了解这种方法是因为确实看见有人这么做过。推荐使用第二种方法,重新绘制图片,不仅可以绘制出四角圆角图片,还可以绘制出底部/顶部/左边/右边圆角效果,非常方便。如果想要偷懒,可以直接使用RoundedBitmapDrawable来实现圆角照片效果。而第三种方法,使用CardView控件有很大的局限性,它只在5.0以及以上的系统中有效。

下面就来看一下各种方法的具体情况吧。

2. 图层叠加

图层叠加原理很简单,就是在一张图片上面叠加一层图,覆盖部分,让图片展示成圆角。具体原理可以参考下面这张图。


图-1 图层叠加原理图

看一下布局代码,很简单。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin">

    <FrameLayout
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@drawable/demo_icon_android_logo">
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:src="@drawable/demo_icon_shader"/>
    </FrameLayout>
</RelativeLayout>

运行结果如下:


图-2 图片叠层运行结果图

       效果还是可以的,但是缺点也很明显,一是要准备两张图片,会增加额外的包体积;二是图片叠加一起,必然导致过度绘制;三是该方法太死板,使用时候要考虑图片大小,控件大小,以及蒙层图圆角锯齿效果,非常不灵活,Java里面不灵活就意味着可用性不强。

       所以这种方法不建议使用,大家作为了解就行。提出这种方法是为了让大家了解一下图层,后面重新绘制过程中,有一种方法逻辑跟这个相似,也是绘制图层叠加,生成圆角图片。

3. 重新绘制

对图片的绘制要特别的注意,有时候可能图片太大需要我们压缩,关于图片压缩大家可以查看这片文章压缩图片。重新绘制图片,将图片绘制成圆角,有三种方法。

  • 使用BitmapShader
  • 使用Xfermode
  • 使用RoundedBitmapDrawable

从性能上讲并没有太大的区别,但是从使用灵活性上说,个人推荐使用BitmapShader。

       在介绍这三个方法之前,先介绍一下图片的拉伸缩放适配,大多数情况先,要展示图片的控件(ImageView)的长宽和图片的长宽并不是一致的,甚至长宽比都不一致,所以在拿到一张图片时候,大多数情况下需要根据控件的大小对图片进行拉伸缩放处理,有人会问为什么不直接使用ImageView属性scaleType去控制拉伸缩放,这是因为当我们将一个Bitmap绘制成圆角后,再去进行拉伸缩放,圆角可能会变形,所以在Bitmap设置到控件之前就需要对Bitmap进行一下拉伸缩放处理,直接看下面代码。

// 图片根据控件大小等比例缩放拉伸
float widthScale = imageViewWidth * 1.0f / bitmap.getWidth();
float heightScale = imageViewHeight * 1.0f / bitmap.getHeight();
// 设置长宽拉伸缩放比
Matrix matrix = new Matrix();
matrix.setScale(widthScale, heightScale);
// 拉伸缩放图片
Bitmap newBt = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);

注:拉伸缩放也可以在Canvas.drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)方法中控制,后面会提及到。

3.1 BitmapShader绘制圆角

       所有的绘制圆角的实现,推荐使用这个方法,不仅仅可以帮助我们实现圆角,连部分圆角都可以实现,比如顶部是两个圆角,底部是两个直角的图片。
       首先介绍一下BitmapShader这个类,它作为纹理用于绘制一张图。新图可以是纹理图重复/镜像/边缘像素拉伸而绘制成的新图。这个类构造函数很简单,BitmapShader(Bitmap bitmap, TileMode tileX, TileMode tileY),第一个参数是Bitmap,作为纹理图传入,tileX是指在水平方向上的绘制方式,tileY是指在竖直方向上的绘制方式。TileMode有三种属性,拉伸、重复、镜像。

  • TileMode.CLAMP 拉伸绘制,并不是指图片拉伸,而是指图片最后一个像素不断绘制,纹理图水平或者竖直方向最后一个
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值