實現圓角圖片的方法有如下幾種,其中的最第三種是參考的Android圓角圖片和圓形圖片實現總結java
val option = RequestOptions()
.error(R.mipmap.ic_launcher_round)
.transform(RoundedCorners(300))//設置圓角半徑
Glide.with(userInfoAvatar)
.applyDefaultRequestOptions(option)
.load(imgUrl)
.into(img)
複製代碼
第四第五兩個方法是評論區大佬給補充的知識,謝謝大佬!android
強烈建議使用ShapeImageView,不只能夠實現四個角的控制還能控制四條邊,就能夠畫出任何想要的異形。具體怎麼實現能夠看一下個人這篇文章Android 實現佈局凹陷(MaterialShapeDrawable)canvas
只須要給這個View設置shapeAppearance屬性就能夠實現對角形狀的控制,以及邊框,先看一下效果:數組
左邊是圓角,右邊是「切角」markdown
<!-- layout.xml 就是在佈局中定義-->
<com.google.android.material.imageview.ShapeableImageView android:layout_width="200dp" android:layout_height="wrap_content" android:scaleType="fitXY" android:strokeWidth="10dp" android:strokeColor="@color/purple" android:src="@drawable/ic_launcher_background" app:shapeAppearance="@style/RoundAndCutImageStyle" />
複製代碼
<!-- style.xml 能夠單獨給每一個角設置屬性-->
<style name="RoundAndCutImageStyle"> <item name="cornerFamilyTopLeft">rounded</item> <item name="cornerFamilyBottomLeft">rounded</item> <item name="cornerFamilyTopRight">cut</item> <item name="cornerFamilyBottomRight">cut</item> <item name="cornerSize">50%</item> <item name="cornerSizeBottomLeft">20dp</item> <item name="cornerSizeTopLeft">20dp</item> </style>
複製代碼
這裏須要解釋如下幾個屬性:app
<!-- 系統主題,使用這個主題的activity包含有material design的控件就會被如下屬性修飾形狀 -->
<style name="MyAppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar"> <item name="shapeAppearanceLargeComponent">@style/ShapeAppearance.MyApp.LargeComponent</item> <item name="shapeAppearanceMediumComponent">@style/ShapeAppearance.MyApp.MediumComponent</item> <item name="shapeAppearanceSmallComponent">@style/ShapeAppearance.MyApp.SmallComponent</item> </style>
<style name="ShapeAppearance.MyApp.MediumComponent" parent="ShapeAppearance.MaterialComponents.MediumComponent"> <item name="cornerFamily">cut</item> <item name="cornerSize">8dp</item> </style>
複製代碼
這兩個屬性能夠單獨給每一個角設置,cornerFamilyTopLeft、cornerSizeTopLet這樣的。框架
我這裏我這裏一樣是使用的BitmapShader來進行從新繪製,大體思路是和那篇文章寫得同樣,可是使用了不一樣的繪製方法,而且也實現了每一個角單獨繪製不過相對上面的那篇文章會簡單一點。開始以前建議先閱讀這篇文章哦Android圓角圖片和圓形圖片實現總結👍ide
官網的中文翻譯 函數
public BitmapShader(Bitmap bitmap,TileMode tileX, TileMode tileY) 複製代碼
paint設置shader以後,當發生繪製時,就會把shader中的bitmap的內容繪製到指定的位置,大體這麼理解,有錯誤歡迎大佬指出,謝謝!oop
private fun drawableToBitmap(drawable: Drawable): Bitmap {
val bitmap = Bitmap.createBitmap(getTrulyWidth(), getTrulyHeight(), Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)//將畫布目標設置爲bitmap,這樣畫布的內容就會直接畫到bitmap上
//這裏傳入的寬高就是減去padding的值
drawable.setBounds(0, 0, getTrulyWidth(), getTrulyHeight())
drawable.draw(canvas)
return bitmap
}
//其實在kotlin中存在一個擴展函數,就是使用kotlin的話直接drawable.toBitmap(...)
fun Drawable.toBitmap( @Px width: Int = intrinsicWidth, @Px height: Int = intrinsicHeight, config: Config? = null): Bitmap
複製代碼
/** * 這個方法經過內外邊框來完成繪製,且內外邊框的四個角的圓角半徑均可控 * @param outer 外邊框的範圍 * @param inner 內邊框的範圍 * @param innerRadii、outerRadii * 這兩個float數組分別保存了內外邊框的四個角的圓角半徑 * 每一個數組須要傳入8個float,每兩個爲一組 rx,ry即圓角半徑在x,y方向的值 * @param paint 這裏我傳入的paint裏面保存着bitmapShader * 此外須要注意設置Style: * FILL將會繪製到兩個矩形(RectF)中間的內容 * STROKE,就是會把兩個邊框給繪製出來。 */
public void drawDoubleRoundRect(@NonNull RectF outer, @NonNull float[] outerRadii, @NonNull RectF inner, @NonNull float[] innerRadii, @NonNull Paint paint) 複製代碼
這個方法的靈活性很高,由於內外邊框均可控。注意 內邊框不能在外邊框的外面,邊界超過外邊框會致使不繪製。邊界能夠相等
這裏爲了簡便沒有給畫筆設置shader,就是單純的黑色。
(這個能看見個人內邊框嗎,內邊框位於view的正中間,寬高都爲0,看不見吧,這樣就已經實現了對四個圓角的控制。)
這裏給出最後一個的繪製代碼
canvas.drawDoubleRoundRect(
outRect,
floatArrayOf(
topLeftRadius,
topLeftRadius,//左上角
topRightRadius,
topRightRadius,//右上角
bottomRightRadius,
bottomRightRadius,//右下角
0f,
0f//左下角
),
//內邊框,恰好是位於中間的0X0的矩形,其實只須要保證內邊框大小爲0就好了
RectF(outWidth/2f,outHeight/2f,outWidth/2f,outHeight/2f),
//內邊框四角半徑
floatArrayOf(
0f,//rx
0f,//ry
0f,
0f,
0f,
0f,
0f,
0f
),
bitmapPaint//style = Paint.Style.FILL 繪製兩個矩形之間的內容;
// bitmap.shader = BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)
)
複製代碼
已知畫筆設置Paint.Style.FILL時,將會繪製兩個矩形之間的內容。那麼兩個邊框有部份內容不重合時會發生什麼呢?(雖然內邊框必須小於等於外邊框,可是當外邊框設置了圓角半徑時,就可能出現兩者存在部份內容不能重合。)
先看一下繪製的邊框:
Paint.Style.STROKE
Paint.Style.FILL
Canvas.drawDoubleRoundRect
這個方法繪製兩個邊框的非交集部分的內容,正好對應PorterDuff.Mode.Xor
詳細內容能夠查看PorterDuff.Mode
內容不免會有錯誤,很是歡迎你們指出,對於你們的建議和錯誤指正,我會及時修改。謝謝!