关于安卓毛玻璃实现(三)recyclerview静态毛玻璃
背景
毛玻璃,開發中又愛又恨的一個話題,玩法層出不窮,有動態的,也有靜態的。有的是實時模糊,有些只需要模糊一次,本文的毛玻璃實現,就是靜態毛玻璃。
開發環境
win 10
as 4+
jdk 1.8
代碼
!!!源碼在文末!!!
最終效果
思路
看到上圖,首先就要觀察有什么要點:
(1)毛玻璃的區域,是與圖片“內容連貫”的,就是說,毛玻璃展示內容,和實際內容一致,視覺上就是“局部毛玻璃”的效果。
(2)毛玻璃的形狀,看上去,毛玻璃四個角都是圓角,所以,就涉及到毛玻璃展示過程中的圓角繪制。
根據要點,可以總結出,原圖,必須要先加載出來,然后設置到ImageView上面,再獲取ImageView正在顯示的圖像(先設置到ImageView,因為會收到其ScaleType屬性影響),然后自定義view對獲取的圖片進行處理即可。
實現
原理說完了,那又要怎么實現呢?列出步驟:
(一)把圖片顯示在背景控件上面
(二)把背景控件顯示后的圖片,傳入到自定義毛玻璃控件中
(三)通過canvas處理,繪制,顯示
下面開始具體描述如何實現:
(一)把圖片顯示在背景控件上面
這一步就是常規操作了,可以用glide,也可以本地隨便搞一個圖片設置到背景控件中即可,筆者這里的demo是通過ImageView xml屬性配置的。
(二)把背景控件顯示后的圖片,傳入到自定義毛玻璃控件中
這里就涉及到一個“獲取顯示控件的圖片”這一個邏輯,具體的實現代碼如下:
/*** 普通截圖*/public static void viewSnapShot(View view, ViewSnapListener listener) {try {//使控件可以進行緩存view.setDrawingCacheEnabled(true);//獲取緩存的 BitmapBitmap drawingCache = view.getDrawingCache();//復制獲取的 BitmapdrawingCache = Bitmap.createBitmap(drawingCache, 0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());//關閉視圖的緩存view.setDrawingCacheEnabled(false);view.destroyDrawingCache();if (drawingCache != null) {if (listener != null) {listener.success(drawingCache);}} else {if (listener != null) {listener.failed("draw cache is null");}}} catch (Exception e) {if (listener != null) {listener.failed(e.getMessage());}}}通過該方法,可以獲取ImageView控件顯示中的圖片,并且返回一個bitmap對象給外部了。
(三)通過canvas處理,繪制,顯示
這里涉及到自定義view。首先,先看xml設置的布局位置,代碼如下:
<RelativeLayoutandroid:layout_width="match_parent"android:layout_height="200dp"><ImageViewandroid:id="@+id/thirdImg"android:layout_width="match_parent"android:layout_height="200dp"android:scaleType="centerCrop"android:src="@drawable/testblur" /><com.example.ktdemo.blur.blurwidget.BlurAlignBottomViewandroid:id="@+id/ivBlurView"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_alignParentBottom="true" /></RelativeLayout>可以看到,自定義毛玻璃控件BlurAlignBottomView的寬高是與背景圖片顯示控件的寬高一樣的。
再說核心實現。因為寬高一樣,所以處理起來,就簡單很多了。
(1)通過clipRect方法,剪裁不需要顯示的區域
(2)最后把bitmap高斯模糊后通過canvas畫上去
對bitmap進行高斯模糊的代碼如下:
public static Bitmap blur(Context context,int blurRadius, Bitmap srcBitmap) {try {float radius = Math.min(25,blurRadius);radius = Math.max(0,radius);Bitmap bitmap = srcBitmap.copy(srcBitmap.getConfig(), true);final RenderScript rs = RenderScript.create(context);final Allocation input = Allocation.createFromBitmap(rs, srcBitmap,Allocation.MipmapControl.MIPMAP_NONE,Allocation.USAGE_SCRIPT);final Allocation output = Allocation.createTyped(rs, input.getType());final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));script.setRadius(radius /* e.g. 3.f */);script.setInput(input);script.forEach(output);output.copyTo(bitmap);return bitmap;} catch (Exception e) {e.printStackTrace();return srcBitmap;}}使用原生RenderScript模糊即可。
剪裁顯示范圍以及繪制bitmap核心代碼如下:
int mesWidth = getMeasuredWidth();int mesHeight = getMeasuredHeight();float radius = mBlurInfo.getRadius();Bitmap mSrcBitmap = mBlurInfo.getSrcBitmap();canvas.save();canvas.clipRect(0, mesHeight - mBlurInfo.getBlurHeight(), mesWidth, mesHeight);RectF canvasRectF = new RectF(0, mesHeight - mBlurInfo.getBlurHeight(), mesWidth, mesHeight);Path mPath = new Path();mPath.addRoundRect(canvasRectF, radius, radius, Path.Direction.CW);canvas.clipPath(mPath);Rect bitmapRect = new Rect(0, 0, mesWidth, mesHeight);canvas.drawBitmap(mSrcBitmap, null, bitmapRect, null);canvas.restore();}總結。實現方式其實用很多,而文中的實現方式,僅僅是眾多方法中的一種而已,各位若有更好的方法請在評論區留言。
代碼地址
搜索BlurAlignBottomView類
that’s all----------------------------------------------------------------------------
總結
以上是生活随笔為你收集整理的关于安卓毛玻璃实现(三)recyclerview静态毛玻璃的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 苹果应用上传TestFlight安装测试
- 下一篇: 脚踏实地的大步流星