Android中实现圆角图片的几种方法

Android中实现圆角图片有多种姿势,不知你解锁了几种?

方法一:setXfermode法

此种方式就是再new一个相同尺寸的bitmap,然后使用paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));先画圆角矩形,再画原始bitmap,然后就得到了一个圆角的bitmap了。

public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) {

  Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
  Canvas canvas = new Canvas(output);

  final int color = 0xff424242;
  final Paint paint = new Paint();
  final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
  final RectF rectF = new RectF(rect);

  paint.setAntiAlias(true);
  canvas.drawARGB(0, 0, 0, 0);
  paint.setColor(color);
  canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

  paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
  canvas.drawBitmap(bitmap, rect, rect, paint);

  return output;
}

点评:

早期用得较多,占用bitmap双倍内存。

方法二:使用BitmapShader

此种方式是先将bitmap生成BitmapShader,然后将其绘制到canvas中, 部分关键代码如下,完整代码请参考QuickAF中的RoundImageView

bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint.setShader(bitmapShader);
@Override
public void draw(Canvas canvas) {
  Rect bounds = getBounds();
  canvas.drawRoundRect(fillRect, radius, radius, paint);
  if (mBorderWidth > 0) {
    if (mIsCircle) {
      canvas.drawCircle(bounds.width() / 2, bounds.height() / 2, radius, strokePaint);
    }
    else {
      canvas.drawRoundRect(fillRect, radius, radius, strokePaint);
    }
  }
}

点评:

占用内存较大,实现有点小复杂。

方法三:图片加载库

目前github上有许多流行的图片加载库,基于上都附带圆角图片功能,只需要稍微配置一下,即可轻松的实现想要的效果。其实在底层,无非也是使用上面的两种方式。比如Android-Universal-Image-Loader 早期的RoundedBitmapDisplayer使用setXfermode来实现,后来使用BitmapShader实现。

DisplayImageOptions options = new DisplayImageOptions.Builder()
    .displayer(new RoundedBitmapDisplayer()) // display rounded bitmap
    .build();

再以比较另类的fresco为例,虽然底层是以C实现,不过在圆角处理上,仍然还是在Java层实现,用的方式还是BitmapShader。不过对于非bitmap的圆角实现,fresco是用Paint直接画的。附上fresco配置。

<com.facebook.drawee.view.SimpleDraweeView
 android:id="@+id/my_image_view"
 android:layout_width="20dp"
 android:layout_height="20dp"
 fresco:fadeDuration="300"
 fresco:actualImageScaleType="focusCrop"
 fresco:placeholderImage="@color/wait_color"
 fresco:placeholderImageScaleType="fitCenter"
 fresco:failureImage="@drawable/error"
 fresco:failureImageScaleType="centerInside"
 fresco:retryImage="@drawable/retrying"
 fresco:retryImageScaleType="centerCrop"
 fresco:progressBarImage="@drawable/progress_bar"
 fresco:progressBarImageScaleType="centerInside"
 fresco:progressBarAutoRotateInterval="1000"
 fresco:backgroundImage="@color/blue"
 fresco:overlayImage="@drawable/watermark"
 fresco:pressedStateOverlayImage="@color/red"
 fresco:roundAsCircle="false"
 fresco:roundedCornerRadius="1dp"
 fresco:roundTopLeft="true"
 fresco:roundTopRight="false"
 fresco:roundBottomLeft="false"
 fresco:roundBottomRight="true"
 fresco:roundWithOverlayColor="@color/corner_color"
 fresco:roundingBorderWidth="2dp"
 fresco:roundingBorderColor="@color/border_color"
/>

点评:

由框架实现,使用简单,稳定。

方法四:遮罩

此种方式还是使用setXfermode,不过与方法一不同的是:不对图片作任何更改,只在圆角之外再画一层与背景颜色相同的四个角来遮挡,在视觉上造成圆角图片的效果。关键代码如下:

@Override
protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  if (src != null && dst != null) {
    int w = getMeasuredWidth(), h = getMeasuredHeight();
    int sc = canvas.saveLayer(0, 0, w, h, null,
      Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG
        | Canvas.FULL_COLOR_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG);
    canvas.drawBitmap(dst, 0, 0, paint); // 圆角矩形
    paint.setXfermode(mode); // new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT);
    canvas.drawBitmap(src, 0, 0, paint); // 长方形
    paint.setXfermode(null);
    canvas.restoreToCount(sc);
  }
}

详细代码请参考QuickAF中的RoundMaskView

使用这种方式,圆角化的对象不限于ImageView,还可以是任意的layout哦,比如下面的示例

<FrameLayout
  android:layout_width="match_parent"
  android:layout_height="wrap_content">

  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <ImageView
      android:layout_width="match_parent"
      android:layout_height="150dp"
      android:src="@color/colorAccent"/>

    <TextView
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:layout_gravity="bottom"
      android:background="@color/black_alpha_50"
      android:padding="12dp"
      android:text="I am text"/>
  </LinearLayout>

  <cn.ieclipse.af.view.RoundMaskView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:radius="10dp"
    app:af_borderColor="@color/white"
    app:af_borderWidth="1dp"/>
</FrameLayout>

配合FrameLayout,将LinearLayout实现了圆角,在视觉效果上,ImageView左上和右上圆角,TextView左下和右下圆角。

点评:

具有一定的局限性,不过不限于图片,所有的Layout都可以在视觉上实现圆角。

关于

QuickAF是一个Android平台上的app快速开发框架。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android如何设置圆角图片

    在开发过程中有时需要将图片显示成圆角图片,一般我们可以通过在xml中设置drawable shape即可,但今天我给出另一种方法,用java代码动态去设置圆角,顺便做个简单的笔记. 主要原理是使用系统自带api: RoundedBitmapDrawableFactory 先上效果图: 由于比较简单,直接给出实现方式: public class MainActivity extends AppCompatActivity { private ImageView mImgRectRound; pri

  • android 设置圆角图片实现代码

    复制代码 代码如下: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/layout" android:orientation="vertical" android:layout_wi

  • Android关于Glide的使用(高斯模糊、加载监听、圆角图片)

    高斯模糊.加载监听.圆角图片这些相信大家都很熟悉,那如何实现这些效果,请大家参考本文进行学习. 1.引用 compile 'com.github.bumptech.glide:glide:3.7.0' 2.加载图片 2.1 基本加载 Glide.with(context)     .load(url)     .into(imageView); 2.2 设置加载中和加载失败的情况 Glide.with(context) .load(url) .placeholder(R.drawable.loa

  • android 实现圆角图片解决方案

    现在我们就来看看怎么样把图片的四角都变成圆形的,为什么要这样做那,如果要是这样界面就会非常的美观,下面我们就来看看代码吧. java代码: 复制代码 代码如下: public static Bitmap toRoundCorner(Bitmap bitmap, int pixels) { Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888); Canvas canv

  • Android中Glide加载圆形图片和圆角图片实例代码

    一.简介: 介绍两种使用 BitmapTransformation 来实现 Glide 加载圆形图片和圆角图片的方法.Glide 并不能直接支持 Round Pictures ,需要使用 BitmapTransformation 来进行处理. 二.网上的实现方式 这里介绍下网上常见的方式和使用 RoundedBitmapDrawable 两种方法,本质上是差不多的: 使用 Canvas 和 Paint 来绘制 使用 Android.support.v4.graphics.drawable.Rou

  • Android 实现圆角图片的简单实例

    Android 实现圆角图片的简单实例 实现效果图: 本来想在网上找个圆角的例子看一看,不尽人意啊,基本都是官方的Demo的那张原理图,稍后会贴出.于是自己自定义了个View,实现图片的圆角以及圆形效果.效果图: Android 圆角图片的实现形式,包括用第三方.也有系统的.比如makeramen:roundedimageview,系统的cardview , glide .fresco . compile 'com.android.support:appcompat-v7:24.0.0' com

  • Android中实现圆角图片的几种方法

    Android中实现圆角图片有多种姿势,不知你解锁了几种? 方法一:setXfermode法 此种方式就是再new一个相同尺寸的bitmap,然后使用paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));先画圆角矩形,再画原始bitmap,然后就得到了一个圆角的bitmap了. public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) { Bitmap

  • Android中button的onClick事件几种方法

    Android中button的onClick事件几种方法 利用三种方法,学习button的监听事件. 方法一源码如下: package com.example.androidtest; import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.view.Menu; import android.widget.Button; import android.

  • Android中Intent传递对象的两种方法Serializable,Parcelable

    Android中的传递有两个方法,一个是Serializable,另一个是Parcelable. Serializable是J2SE本身就支持的.而Parcelable是Android所特有的. 二者的使用场景和区别: 1)在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable. 2)Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC. 3)Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelab

  • Android中实现毛玻璃效果的3种方法

    最近在做一款叫叽叽的App(男银懂的),其中有一个功能需要对图片处理实现毛玻璃的特效 进过一番预研,找到了3中实现方案,其中各有优缺点: 1.如果系统的api在16以上,可以使用系统提供的方法直接处理图片 复制代码 代码如下: if (VERSION.SDK_INT > 16) {             Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true); final RenderScript rs = RenderScr

  • Android中自定义标题栏样式的两种方法

    原装的Android标题栏配色比较单调,就是黑色的一坨,现在假设你的软件需要独自添加标题栏,这样不仅美观而且可以将进度条等加进去,如何实现: 方法一.在你的那张Activity中onCreate方法中加上下面代码: requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); setContentView(R.layout.main); //软件activity的布局 getWindow().setFeatureInt(Window.FEATURE_CUS

  • Android中获取状态栏高度的两种方法分享

    前言 最近在做一个关于FAB的功能的时候需要获取状态栏的高度,在网上查了很多种方法,下面是选出的比较合理的两个方法.主要参考stackoverflow的这篇问答:http://stackoverflow.com/questions/3407256/height-of-status-bar-in-android 方法一: private double getStatusBarHeight(Context context){ double statusBarHeight = Math.ceil(25

  • android中Webview实现截屏三种方式小结

    本人最近学习了android中Webview实现截屏三种方式,下面我来记录一下,有需要了解的朋友可参考.希望此文章对各位有所帮助. 第一种方式 通过调用webview.capturePicture(),得到一个picture对象,根据图像的宽和高创建一个Bitmap,再创建一个canvas,绑定bitmap,最后用picture去绘制. //获取Picture对象 Picture picture = wv_capture.capturePicture(); //得到图片的宽和高(没有reflec

  • Android中简单调用图片、视频、音频、录音和拍照的方法

    本文实例讲述了Android中简单调用图片.视频.音频.录音和拍照的方法.分享给大家供大家参考,具体如下: //选择图片 requestCode 返回的标识 Intent innerIntent = new Intent(Intent.ACTION_GET_CONTENT); //"android.intent.action.GET_CONTENT" innerIntent.setType(contentType); //查看类型 String IMAGE_UNSPECIFIED =

  • 基于Android在布局中动态添加view的两种方法(总结)

    一.说明 添加视图文件的时候有两种方式:1.通过在xml文件定义layout:2.java代码编写 二.前言说明 1.构造xml文件 2.LayoutInflater 提到addview,首先要了解一下LayoutInflater类.这个类最主要的功能就是实现将xml表述的layout转化为View的功能.为了便于理解,我们可以将它与findViewById()作一比较,二者都是实例化某一对象,不同的是findViewById()是找xml布局文件下的具体widget控件实例化,而LayoutI

  • 在Qt中正确的设置窗体的背景图片的几种方法总结

    Qt中正确的设置窗体的背景图片的方法大致有两种,下面将逐个讲解: 一. 利用styleSheet设置窗体的背景图片 使用stylesheet设置窗体的背景图片的时候,可以直接按照下图的操作去进行即可,如下图所示: 但是,需要注意的是: 1.在QWidget中这种方法是不行的,如果你足够细心的话,你会发现使用同样的设置背景图片的方法,背景图片其实并没有发生真实改变,但是它的子窗体背景图片是会发生改变的. 其实我们可以通过在添加一个i额QWidget来解决这个问题,即在QtDesigner中添加一个

随机推荐