欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2023-11-04 16:03:04
android中实现圆角图片有多种姿势,不知你解锁了几种? 方法一:setxfermode法 此种方式就是再new一个相同尺寸的bitmap,然后使用paint.set...

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快速开发框架。

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