編輯:關於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快速開發框架。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持本站。
微信的用戶數量日益增多,甚至有取代qq的趨勢,當我們跟一群人參加戶外活動的時候想加其他人的微信好友,您是不是要一個個的掃二維碼添加呢,那麼下面就
仿微信通訊錄右側快速定位字母表控件先看效果圖: 界面比較單調,湊合看,主要看功能。這種控件在很多應用的通訊錄的界面,MIUI裡面的通訊錄都有這個功能,其實這是一
近日關於iPhone和Android手機跟蹤用戶位置的問題受到手機用戶們的關注,盡管這些都是所謂的基於位置服務的必要信息,但是依然與用戶隱私有關。證據顯示,
在前面的一篇文章中,簡單的介紹了一下如何實現軟鍵盤不自動彈出,使用的方法是設置android:windowSoftInputMode屬性。那麼,這個屬性到底是干什麼的,他