@@ -11,9 +11,11 @@ import androidx.compose.foundation.Canvas
1111import androidx.compose.foundation.Image
1212import androidx.compose.foundation.background
1313import androidx.compose.foundation.border
14+ import androidx.compose.foundation.clickable
1415import androidx.compose.foundation.layout.Arrangement
1516import androidx.compose.foundation.layout.Box
1617import androidx.compose.foundation.layout.Column
18+ import androidx.compose.foundation.layout.PaddingValues
1719import androidx.compose.foundation.layout.Spacer
1820import androidx.compose.foundation.layout.aspectRatio
1921import androidx.compose.foundation.layout.fillMaxSize
@@ -22,21 +24,22 @@ import androidx.compose.foundation.layout.height
2224import androidx.compose.foundation.layout.padding
2325import androidx.compose.foundation.layout.width
2426import androidx.compose.foundation.lazy.LazyColumn
27+ import androidx.compose.foundation.lazy.LazyRow
28+ import androidx.compose.foundation.lazy.rememberLazyListState
2529import androidx.compose.foundation.rememberScrollState
2630import androidx.compose.foundation.shape.RoundedCornerShape
2731import androidx.compose.foundation.verticalScroll
2832import androidx.compose.material3.Slider
2933import androidx.compose.material3.Text
3034import androidx.compose.runtime.Composable
31- import androidx.compose.runtime.LaunchedEffect
3235import androidx.compose.runtime.getValue
3336import androidx.compose.runtime.mutableFloatStateOf
34- import androidx.compose.runtime.mutableIntStateOf
3537import androidx.compose.runtime.remember
3638import androidx.compose.runtime.setValue
3739import androidx.compose.ui.Alignment
3840import androidx.compose.ui.Modifier
3941import androidx.compose.ui.draw.clipToBounds
42+ import androidx.compose.ui.draw.drawWithCache
4043import androidx.compose.ui.draw.drawWithContent
4144import androidx.compose.ui.geometry.Offset
4245import androidx.compose.ui.graphics.Brush
@@ -59,15 +62,16 @@ import androidx.compose.ui.platform.LocalDensity
5962import androidx.compose.ui.res.imageResource
6063import androidx.compose.ui.res.painterResource
6164import androidx.compose.ui.tooling.preview.Preview
65+ import androidx.compose.ui.unit.Dp
6266import androidx.compose.ui.unit.IntSize
6367import androidx.compose.ui.unit.dp
68+ import androidx.compose.ui.unit.roundToIntSize
6469import androidx.compose.ui.unit.sp
6570import com.smarttoolfactory.tutorial1_1basics.R
6671import com.smarttoolfactory.tutorial1_1basics.ui.backgroundColor
6772import com.smarttoolfactory.tutorial1_1basics.ui.components.StyleableTutorialText
6873import com.smarttoolfactory.tutorial1_1basics.ui.components.TutorialHeader
6974import com.smarttoolfactory.tutorial1_1basics.ui.components.TutorialText2
70- import kotlinx.coroutines.delay
7175import org.intellij.lang.annotations.Language
7276import kotlin.math.roundToInt
7377
@@ -77,7 +81,6 @@ fun Tutorial6_40Screen2() {
7781 TutorialContent ()
7882}
7983
80-
8184@Composable
8285private fun TutorialContent () {
8386 Column (modifier = Modifier .padding(8 .dp)) {
@@ -507,19 +510,11 @@ fun RenderNodeSample() {
507510
508511 val graphicsLayer = rememberGraphicsLayer()
509512
510- var counter by remember {
511- mutableIntStateOf(0 )
512- }
513-
514- LaunchedEffect (Unit ) {
515- while (true ) {
516- delay(60 )
517- counter++
518- }
519- }
513+ val state = rememberLazyListState()
520514
521515 Box {
522516 LazyColumn (
517+ state = state,
523518 modifier = Modifier
524519 .background(backgroundColor)
525520 .fillMaxSize()
@@ -536,20 +531,6 @@ fun RenderNodeSample() {
536531 ) {
537532 this @drawWithContent.drawContent()
538533 }
539-
540- // val recordingCanvas = contentNode.beginRecording()
541- // canvasHolder.drawInto(recordingCanvas) {
542- // drawContext.also {
543- // it.layoutDirection = layoutDirection
544- // it.size = size
545- // it.canvas = this
546- // }
547- // // this@drawWithContent.drawContent()
548- // drawLayer(graphicsLayer)
549- // }
550- //
551- // contentNode.endRecording()
552-
553534 },
554535 verticalArrangement = Arrangement .spacedBy(8 .dp)
555536 ) {
@@ -600,8 +581,6 @@ fun RenderNodeSample() {
600581 )
601582 )
602583
603- println (" Drawing...$counter " )
604-
605584 drawIntoCanvas { canvas: Canvas ->
606585 val recordingCanvas = contentNode.beginRecording()
607586 canvasHolder.drawInto(recordingCanvas) {
@@ -626,4 +605,165 @@ fun RenderNodeSample() {
626605 )
627606 }
628607 }
608+ }
609+
610+ fun Modifier.frostedGlass (height : Dp ) = this .then(
611+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .S ) {
612+ Modifier .drawWithCache {
613+ val topBarHeightPx = height.toPx()
614+
615+ val blurLayer = obtainGraphicsLayer().apply {
616+ renderEffect = RenderEffect
617+ .createBlurEffect(16f , 16f , Shader .TileMode .DECAL )
618+ .asComposeRenderEffect()
619+ }
620+
621+ onDrawWithContent {
622+ blurLayer.record(size.copy(height = topBarHeightPx).roundToIntSize()) {
623+ this @onDrawWithContent.drawContent()
624+ }
625+
626+ drawLayer(blurLayer)
627+ clipRect(top = topBarHeightPx) {
628+ this @onDrawWithContent.drawContent()
629+ }
630+ }
631+ }
632+ } else {
633+ Modifier
634+ }
635+ )
636+
637+ @RequiresApi(Build .VERSION_CODES .TIRAMISU )
638+ @Preview(showBackground = true )
639+ @Composable
640+ fun PartialBlurTest () {
641+
642+ val scrollState = rememberLazyListState()
643+ val topBarHeight = 180 .dp
644+
645+ LazyColumn (
646+ state = scrollState,
647+ modifier = Modifier
648+ .fillMaxSize()
649+ .frostedGlass(height = topBarHeight),
650+ verticalArrangement = Arrangement .spacedBy(8 .dp)
651+ ) {
652+
653+ item {
654+ Spacer (modifier = Modifier .height(topBarHeight))
655+ }
656+
657+ item {
658+ LazyRow (
659+ modifier = Modifier .fillMaxWidth().aspectRatio(2f ),
660+ contentPadding = PaddingValues (horizontal = 16 .dp),
661+ horizontalArrangement = Arrangement .spacedBy(8 .dp)
662+ ) {
663+ items(5 ) {
664+ Image (
665+ modifier = Modifier
666+ .fillParentMaxWidth()
667+ .aspectRatio(2f ),
668+ contentScale = ContentScale .Crop ,
669+ painter = painterResource(R .drawable.landscape11), contentDescription = null
670+ )
671+ }
672+ }
673+ }
674+ items(100 ) {
675+ if (it == 5 ) {
676+ Image (
677+ modifier = Modifier
678+ .fillMaxWidth()
679+ .aspectRatio(.5f ),
680+ painter = painterResource(R .drawable.landscape11),
681+ contentScale = ContentScale .Crop ,
682+ contentDescription = null
683+ )
684+ } else {
685+ Box (
686+ modifier = Modifier
687+ .clickable {
688+
689+ }
690+ .fillMaxWidth()
691+ .background(Color .White , RoundedCornerShape (16 .dp))
692+ .padding(16 .dp)
693+ ) {
694+ Text (" Row $it " , fontSize = 22 .sp)
695+ }
696+ }
697+ }
698+ }
699+ }
700+
701+
702+ @Language(" GLSL" )
703+ val CheapFrostedGlassTopBarAGSL =
704+ """
705+ const vec4 white = vec4(1.0);
706+
707+ uniform shader inputShader;
708+ uniform float barHeight;
709+
710+ vec4 main(vec2 coord) {
711+ if (coord.y > barHeight) {
712+ return inputShader.eval(coord);
713+ } else {
714+ vec2 factor = vec2(3.0);
715+
716+ vec4 color = vec4(0.0);
717+ color += inputShader.eval(coord - 3.0 * factor) * 0.0540540541;
718+ color += inputShader.eval(coord - 2.0 * factor) * 0.1216216216;
719+ color += inputShader.eval(coord - factor) * 0.1945945946;
720+ color += inputShader.eval(coord) * 0.2270270270;
721+ color += inputShader.eval(coord + factor) * 0.1945945946;
722+ color += inputShader.eval(coord + 2.0 * factor) * 0.1216216216;
723+ color += inputShader.eval(coord + 3.0 * factor) * 0.0540540541;
724+
725+ return mix(color, white, 0.7);
726+ }
727+ }
728+ """ .trimIndent()
729+
730+ val TopAppBarHeight = 180 .dp
731+
732+ @RequiresApi(Build .VERSION_CODES .TIRAMISU )
733+ @Preview(showBackground = true )
734+ @Composable
735+ fun FrostedGlassTopBarTest () {
736+ LazyColumn (
737+ modifier = Modifier
738+ .fillMaxSize()
739+ .graphicsLayer {
740+ val shader = RuntimeShader (CheapFrostedGlassTopBarAGSL )
741+ shader.setFloatUniform(" barHeight" , TopAppBarHeight .toPx())
742+ val androidRenderEffect = android.graphics.RenderEffect
743+ .createRuntimeShaderEffect(shader, " inputShader" )
744+ renderEffect = androidRenderEffect.asComposeRenderEffect()
745+ }
746+ ) {
747+ items(100 ) {
748+ if (it == 5 ) {
749+ Image (
750+ modifier = Modifier
751+ .fillMaxWidth()
752+ .aspectRatio(2f ),
753+ painter = painterResource(R .drawable.landscape11),
754+ contentScale = ContentScale .Crop ,
755+ contentDescription = null
756+ )
757+ } else {
758+ Box (
759+ modifier = Modifier
760+ .fillMaxWidth()
761+ .background(Color .White , RoundedCornerShape (16 .dp))
762+ .padding(16 .dp)
763+ ) {
764+ Text (" Row $it " , fontSize = 22 .sp)
765+ }
766+ }
767+ }
768+ }
629769}
0 commit comments