Android 弹出对话框背景模糊
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 } }
醉过海阔天空,且狂且痴且醉趁年少