Android 彈出對話框背景模糊使用kotlin實現。
實現思路如下:
1.獲取頂層活動ActivityA
2.截取ActivityA圖片
3.高斯面模糊截取的圖片
4.隱藏頂層ActivityA所有組件
5.設置頂層ActivityA背景圖片
6.對話框退出設置頂層ActivityA背景原來顏色,並且將所有組件顯示
效果圖片
對話框相關代碼
1 val dialog = AlertDialog.Builder(this).setView(R.layout.dialogbox).create() 2 //設置對話框寬度尺寸 3 val windowManager = windowManager 4 val display = windowManager.defaultDisplay 5 val lp = dialog.window!!.attributes 6 lp.width = display.width 7 dialog.window!!.attributes = lp 8 //設置背景高斯模糊 9 this.setBlurredBackground(true) 10 dialog.show()
設置ActivityA背景
private fun setBlurredBackground(blurry:Boolean){ if (blurry){ //高斯模糊背景 val overlay= GaussianBlur.setFastblur(GaussianBlur.takeScreenShot(this)) // 設置背景圖片 window.setBackgroundDrawable(BitmapDrawable(this.resources, overlay)) // findViewById<LinearLayout>(R.id.dialog).setBackgroundDrawable(BitmapDrawable(this.resources, overlay)) setHideView(false) }else{
// 還原背景顏色 window.setBackgroundDrawable(resources.getDrawable(R.color.color_main)) setHideView(true) } }
隱藏View方法
1 //隱藏View 2 private fun setHideView(hide:Boolean){ 3 if (hide){ 4 ButSearch.visibility = View.VISIBLE 5 ButAdd.visibility = View.VISIBLE 6 bnView.visibility= View.VISIBLE 7 title.visibility=View.VISIBLE 8 findViewById<LinearLayout>(R.id.lin_lay_fragment).visibility=View.VISIBLE 9 10 }else{ 11 ButSearch.visibility = View.GONE 12 ButAdd.visibility = View.GONE 13 bnView.visibility= View.GONE 14 title.visibility=View.GONE 15 findViewById<LinearLayout>(R.id.lin_lay_fragment).visibility=View.GONE 16 } 17 }
截取ActivityA方法
1 /** 2 * 截屏 3 * @param activity 截屏的activity 4 * @return 截屏圖片 5 */ 6 fun takeScreenShot(activity: Activity): Bitmap { 7 val view = activity.window.decorView 8 view.isDrawingCacheEnabled = true 9 view.buildDrawingCache() 10 val b1 = view.drawingCache 11 // 獲取屏幕長和高 12 val width = activity.resources.displayMetrics.widthPixels 13 val height = activity.resources.displayMetrics.heightPixels 14 val bmp = Bitmap.createBitmap(b1, 0, 0, width, height) 15 view.destroyDrawingCache() 16 return bmp 17 }
高斯模糊工具類具體代碼
object GaussianBlur { /** * 截屏 * @param activity 截屏的activity * @return 截屏圖片 */ fun takeScreenShot(activity: Activity): Bitmap { val view = activity.window.decorView view.isDrawingCacheEnabled = true view.buildDrawingCache() val b1 = view.drawingCache // 獲取屏幕長和高 val width = activity.resources.displayMetrics.widthPixels val height = activity.resources.displayMetrics.heightPixels val bmp = Bitmap.createBitmap(b1, 0, 0, width, height) view.destroyDrawingCache() return bmp } fun setFastblur(bitmap: Bitmap): Bitmap?{ var bit = small(bitmap)?.let { blurry( it,6) } return bit?.let { big(it) } } /** * 放大圖片 * @param bitmap 需要放大的圖片 * @return 放大的圖片 */ private fun big(bitmap: Bitmap): Bitmap? { val matrix = Matrix() matrix.postScale(4f, 4f) return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true) } /** * 縮小圖片 * @param bitmap 需要縮小的圖片 * @return 縮小的圖片 */ private fun small(bitmap: Bitmap): Bitmap? { val matrix = Matrix() matrix.postScale(0.25f, 0.25f) return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true) } /** 將圖片模糊化 @param sentBitmap 需要模糊的圖片 @param radius 模糊程度 @return 模糊后的圖片 */ private fun blurry(sentBitmap: Bitmap, radius: Int): Bitmap? { val bitmap = sentBitmap.copy(sentBitmap.config, true) if (radius < 1) { return null } val w = bitmap.width val h = bitmap.height val pix = IntArray(w * h) bitmap.getPixels(pix, 0, w, 0, 0, w, h) val wm = w - 1 val hm = h - 1 val wh = w * h val div = radius + radius + 1 val r = IntArray(wh) val g = IntArray(wh) val b = IntArray(wh) var rsum: Int var gsum: Int var bsum: Int var x: Int var y: Int var i: Int var p: Int var yp: Int var yi: Int var yw: Int val vmin = IntArray(w.coerceAtLeast(h)) var divsum = div + 1 shr 1 divsum *= divsum val dv = IntArray(256 * divsum) i = 0 while (i < 256 * divsum) { dv[i] = i / divsum i++ } yi = 0 yw = yi val stack = Array(div) { IntArray(3) } var stackpointer: Int var stackstart: Int var sir: IntArray var rbs: Int val r1 = radius + 1 var routsum: Int var goutsum: Int var boutsum: Int var rinsum: Int var ginsum: Int var binsum: Int y = 0 while (y < h) { bsum = 0 gsum = bsum rsum = gsum boutsum = rsum goutsum = boutsum routsum = goutsum binsum = routsum ginsum = binsum rinsum = ginsum i = -radius while (i <= radius) { p = pix[yi + wm.coerceAtMost(i.coerceAtLeast(0))] sir = stack[i + radius] sir[0] = p and 0xff0000 shr 16 sir[1] = p and 0x00ff00 shr 8 sir[2] = p and 0x0000ff rbs = r1 - abs(i) rsum += sir[0] * rbs gsum += sir[1] * rbs bsum += sir[2] * rbs if (i > 0) { rinsum += sir[0] ginsum += sir[1] binsum += sir[2] } else { routsum += sir[0] goutsum += sir[1] boutsum += sir[2] } i++ } stackpointer = radius x = 0 while (x < w) { r[yi] = dv[rsum] g[yi] = dv[gsum] b[yi] = dv[bsum] rsum -= routsum gsum -= goutsum bsum -= boutsum stackstart = stackpointer - radius + div sir = stack[stackstart % div] routsum -= sir[0] goutsum -= sir[1] boutsum -= sir[2] if (y == 0) { vmin[x] = (x + radius + 1).coerceAtMost(wm) } p = pix[yw + vmin[x]] sir[0] = p and 0xff0000 shr 16 sir[1] = p and 0x00ff00 shr 8 sir[2] = p and 0x0000ff rinsum += sir[0] ginsum += sir[1] binsum += sir[2] rsum += rinsum gsum += ginsum bsum += binsum stackpointer = (stackpointer + 1) % div sir = stack[stackpointer % div] routsum += sir[0] goutsum += sir[1] boutsum += sir[2] rinsum -= sir[0] ginsum -= sir[1] binsum -= sir[2] yi++ x++ } yw += w y++ } x = 0 while (x < w) { bsum = 0 gsum = bsum rsum = gsum boutsum = rsum goutsum = boutsum routsum = goutsum binsum = routsum ginsum = binsum rinsum = ginsum yp = -radius * w i = -radius while (i <= radius) { yi = 0.coerceAtLeast(yp) + x sir = stack[i + radius] sir[0] = r[yi] sir[1] = g[yi] sir[2] = b[yi] rbs = r1 - abs(i) rsum += r[yi] * rbs gsum += g[yi] * rbs bsum += b[yi] * rbs if (i > 0) { rinsum += sir[0] ginsum += sir[1] binsum += sir[2] } else { routsum += sir[0] goutsum += sir[1] boutsum += sir[2] } if (i < hm) { yp += w } i++ } yi = x stackpointer = radius y = 0 while (y < h) { pix[yi] = -0x1000000 and pix[yi] or (dv[rsum] shl 16) or (dv[gsum] shl 8) or dv[bsum] rsum -= routsum gsum -= goutsum bsum -= boutsum stackstart = stackpointer - radius + div sir = stack[stackstart % div] routsum -= sir[0] goutsum -= sir[1] boutsum -= sir[2] if (x == 0) { vmin[y] = (y + r1).coerceAtMost(hm) * w } p = x + vmin[y] sir[0] = r[p] sir[1] = g[p] sir[2] = b[p] rinsum += sir[0] ginsum += sir[1] binsum += sir[2] rsum += rinsum gsum += ginsum bsum += binsum stackpointer = (stackpointer + 1) % div sir = stack[stackpointer] routsum += sir[0] goutsum += sir[1] boutsum += sir[2] rinsum -= sir[0] ginsum -= sir[1] binsum -= sir[2] yi += w y++ } x++ } bitmap.setPixels(pix, 0, w, 0, 0, w, h) return bitmap } }