Android 必知必会-使用 supportV4 的 RoundedBitmapDrawable 实现圆角

RoundedBitmapDrawablesupportV4 下的一个类,有了它,显示圆角和圆形图片的情况下就不需要额外的第三方类库了,还能和各种图片加载库配合使用。

背景

今天无意间看到一段实现圆形头像的代码:

1
2
RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory.create(getResources(), bitmap);
drawable.setCircular(true);

RoundedBitmapDrawable 这个类顿时就引起我的好奇了,一查发现是 android.support.v4.graphics.drawable.RoundedBitmapDrawable点击此处 可以看到官方的介绍。这个类中的两个方法是今天的主角:

return method
void setCircular(boolean circular) : Sets the image shape to circular.
void setCornerRadius(float cornerRadius) : Sets the corner radius to be applied when drawing the bitmap.

setCircular(boolean circular) : 把图片的形状设为圆形;

setCornerRadius(float cornerRadius) : 设置图片的圆角半径。

这里贴一下源码,更能清晰的知道它的实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/**
* Sets the image shape to circular.
* <p>This overwrites any calls made to {@link #setCornerRadius(float)} so far.</p>
*/
public void setCircular(boolean circular) {
mIsCircular = circular;
mApplyGravity = true;
if (circular) {
updateCircularCornerRadius();
mPaint.setShader(mBitmapShader);
invalidateSelf();
} else {
setCornerRadius(0);
}
}

private void updateCircularCornerRadius() {
final int minCircularSize = Math.min(mBitmapHeight, mBitmapWidth);
mCornerRadius = minCircularSize / 2;
}

/**
* Sets the corner radius to be applied when drawing the bitmap.
*/
public void setCornerRadius(float cornerRadius) {
if (mCornerRadius == cornerRadius) return;

mIsCircular = false;
if (isGreaterThanZero(cornerRadius)) {
mPaint.setShader(mBitmapShader);
} else {
mPaint.setShader(null);
}

mCornerRadius = cornerRadius;
invalidateSelf();
}

至于具体的实现,阅读源码发现官方使用了 BitmapShader 来实现的圆角。

如果你有兴趣研究,更多资料:

实现

先看效果图:

2016-08-25_08104B752A742F5F71AE7F16661CBA2A.jpg

其中第一个图片是圆形,第二个和第三个图片设置了自定义大小的圆角。

xxActivity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private void init() {
RoundedBitmapDrawable drawableA = RoundedBitmapDrawableFactory.create(getResources(), id2Bitmap(this, R.drawable.icon_avatar));
drawableA.setCircular(true);
rbA.setImageDrawable(drawableA);

RoundedBitmapDrawable drawableB = RoundedBitmapDrawableFactory.create(getResources(), id2Bitmap(this, R.drawable.icon_avatar));
drawableB.setCornerRadius(30L);
rbB.setImageDrawable(drawableB);

RoundedBitmapDrawable drawableC = RoundedBitmapDrawableFactory.create(getResources(), id2Bitmap(this, R.drawable.icon_avatar));
drawableC.setCornerRadius(60L);
rbC.setImageDrawable(drawableC);
}

public static Bitmap id2Bitmap(Context context, int id) {
return BitmapFactory.decodeResource(context.getResources(), id);
}

activity_xx.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
>

<ImageView
android:id="@+id/rb_a"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>

<ImageView
android:id="@+id/rb_b"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
/>

<ImageView
android:id="@+id/rb_c"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
/>

</LinearLayout>

代码比较简单,有什么问题欢迎随时和我联系。

总结

一个小小的发现,让我又少使用了一个第三方库,心情大好。另外在此过程中发现的 BitmapShader 是学习自定义 View 的一个不错的切入点,需要再研究研究。

PS:你可以通过下面的方式和我联系