Created
October 7, 2023 13:36
-
-
Save ruthwikkk/e0065056b03a62785eb3a32ad48bed0b to your computer and use it in GitHub Desktop.
Final Code for BlurSurface
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Composable | |
fun BlurSurface( | |
modifier: Modifier, | |
parent: ViewGroup | |
) { | |
Surface( | |
modifier = modifier, | |
color = Color.Transparent | |
) { | |
AndroidView( | |
factory = { | |
BlurSurfaceView(parent.context) | |
}, | |
modifier = Modifier | |
.fillMaxSize(), | |
update = { blurView -> | |
blurView.setParent( | |
parent = parent | |
) | |
} | |
) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class BlurSurfaceView: View { | |
private var canvas: Canvas? = null | |
private lateinit var bitmap: Bitmap | |
private lateinit var parent: ViewGroup | |
private var renderScript: RenderScript? = null | |
private lateinit var blurScript: ScriptIntrinsicBlur | |
private lateinit var outAllocation: Allocation | |
constructor(context: Context) : super(context) | |
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) | |
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { | |
super.onSizeChanged(w, h, oldw, oldh) | |
init(measuredWidth, measuredHeight) | |
} | |
private fun init(measuredWidth: Int, measuredHeight: Int) { | |
bitmap = Bitmap.createBitmap( | |
measuredWidth, | |
measuredHeight, | |
Bitmap.Config.ARGB_8888 | |
) | |
canvas = Canvas(bitmap) | |
} | |
override fun onDraw(canvas: Canvas) { | |
super.onDraw(canvas) | |
canvas.save() | |
canvas.drawBitmap(bitmap, 0f, 0f, null) | |
canvas.restore() | |
} | |
private fun getBackgroundAndDrawBehind() { | |
//Arrays to store the co-ordinates | |
val rootLocation = IntArray(2) | |
val viewLocation = IntArray(2) | |
parent.getLocationOnScreen(rootLocation) //get the parent co-ordinates | |
this.getLocationOnScreen(viewLocation) //get view co-ordinates | |
//Calculate relative co-ordinates | |
val left: Int = viewLocation[0] - rootLocation[0] | |
val top: Int = viewLocation[1] - rootLocation[1] | |
canvas?.save() | |
canvas?.translate(-left.toFloat(), -top.toFloat()) //translates the initial position | |
canvas?.let { | |
parent.draw(it) | |
} | |
canvas?.restore() | |
blurWithRenderScript() | |
} | |
private fun blurWithRenderScript() { | |
renderScript = RenderScript.create(context) | |
blurScript = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript)) | |
val inAllocation = Allocation.createFromBitmap(renderScript, bitmap) | |
outAllocation = Allocation.createTyped(renderScript, inAllocation.type) | |
blurScript.setRadius(20f) | |
blurScript.setInput(inAllocation) | |
blurScript.forEach(outAllocation) | |
outAllocation.copyTo(bitmap) | |
inAllocation.destroy() | |
} | |
fun setParent(parent: ViewGroup){ | |
this.parent = parent | |
this.parent.viewTreeObserver.removeOnPreDrawListener(drawListener) | |
this.parent.viewTreeObserver.addOnPreDrawListener(drawListener) | |
} | |
private val drawListener = | |
ViewTreeObserver.OnPreDrawListener { | |
getBackgroundAndDrawBehind() | |
true | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class MainActivity : ComponentActivity() { | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
val decorView = window.decorView | |
val rootView = decorView.findViewById(android.R.id.content) as ViewGroup | |
setContent { | |
Theme { | |
Surface( | |
modifier = Modifier.fillMaxSize(), | |
color = Color.Black | |
) { | |
val context = LocalContext.current | |
Box( | |
modifier = Modifier | |
.fillMaxSize() | |
.horizontalScroll(rememberScrollState()) | |
) { | |
Image( | |
painter = painterResource(id = R.drawable.background), | |
contentDescription = "background", | |
contentScale = ContentScale.FillHeight | |
) | |
} | |
Box( | |
modifier = Modifier | |
.wrapContentSize() | |
.border( | |
width = 2.dp, | |
color = Color.Yellow | |
) | |
) { | |
BlurSurface( | |
modifier = Modifier.size(240.dp), | |
parent = rootView | |
) | |
} | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment