علاوهبر ترکیبپذیر Canvas، Compose چندین گرافیک مفید دارد
Modifiers که به ترسیم محتوای سفارشی کمک میکند. این اصلاحکنندهها مفید هستند
زیرا میتوان آنها را برای هر ترکیبپذیری اعمال کرد.
اصلاحکنندههای طراحی
همه فرمانهای طراحی با اصلاحکننده طراحی در Compose انجام میشود. سه اصلاحکننده اصلی طراحی در Compose وجود دارد:
اصلاحکننده پایه برای ترسیم drawWithContent است که در آن میتوانید ترتیب ترسیم Composable و فرمانهای ترسیم صادرشده در اصلاحکننده را تعیین کنید. drawBehind یک پوشاننده مناسب برای drawWithContent است که
ترتیب ترسیم آن در پشت محتوای قابلترکیب تنظیم شده است. drawWithCache
onDrawBehind یا onDrawWithContent را در داخل خود فراخوانی میکند - و
سازوکاری برای ذخیره کردن اشیای ایجادشده در آنها در حافظه نهان ارائه میدهد.
Modifier.drawWithContent: انتخاب ترتیب ترسیم
Modifier.drawWithContent به شما امکان میدهد
عملیات DrawScope را قبل یا بعداز محتوای
ترکیبپذیر اجرا کنید. حتماً drawContent را فراخوانی کنید تا سپس محتوای واقعی
ترکیبپذیر را ارائه دهید. با این اصلاحکننده، میتوانید ترتیب عملیات را تعیین کنید، مثلاً اگر
بخواهید محتوایتان قبل یا بعداز عملیات ترسیم سفارشی شما
ترسیم شود.
برای مثال، اگر میخواستید یک گرادیان شعاعی را روی محتوای خود رندر کنید تا یک جلوه سوراخ کلید چراغ قوه در رابط کاربری ایجاد کنید، میتوانید کارهای زیر را انجام دهید:
var pointerOffset by remember { mutableStateOf(Offset(0f, 0f)) } Column( modifier = Modifier .fillMaxSize() .pointerInput("dragging") { detectDragGestures { change, dragAmount -> pointerOffset += dragAmount } } .onSizeChanged { pointerOffset = Offset(it.width / 2f, it.height / 2f) } .drawWithContent { drawContent() // draws a fully black area with a small keyhole at pointerOffset that’ll show part of the UI. drawRect( Brush.radialGradient( listOf(Color.Transparent, Color.Black), center = pointerOffset, radius = 100.dp.toPx(), ) ) } ) { // Your composables here }
Modifier.drawBehind: Drawing behind a composable
Modifier.drawBehind به شما امکان میدهد
DrawScope عملیات را در پشت محتوای قابلترکیب که روی صفحه کشیده شده است انجام دهید. اگر
به پیادهسازی Canvas نگاهی بیندازید، ممکن است متوجه شوید که
فقط یک پوشاننده مناسب برای Modifier.drawBehind است.
برای کشیدن مستطیل گردشده در پشت Text:
Text( "Hello Compose!", modifier = Modifier .drawBehind { drawRoundRect( Color(0xFFBBAAEE), cornerRadius = CornerRadius(10.dp.toPx()) ) } .padding(4.dp) )
که نتیجه زیر را تولید میکند:
Modifier.drawWithCache: رسم و ذخیره کردن اشیای رسم در حافظه نهان
Modifier.drawWithCache اشیایی را که در داخل آن ایجاد شدهاند در حافظه نهان نگه میدارد. تا زمانی که اندازه ناحیه طراحی یکسان باشد یا هر شیء وضعیتی که خوانده میشود تغییر نکرده باشد، اشیاء در حافظه نهان ذخیره میشوند. این اصلاحکننده برای بهبود عملکرد فراخوانیهای ترسیم مفید است زیرا
نیاز به تخصیص مجدد اشیاء (مانند: Brush, Shader, Path و غیره)
که در زمان ترسیم ایجاد میشوند را ازبین میبرد.
یا اینکه میتوانید اشیاء را بااستفاده از remember، خارج از اصلاحکننده، ذخیره موقت کنید. بااینحال، این کار همیشه ممکن نیست زیرا همیشه به ترکیببندی دسترسی ندارید. اگر از اشیاء فقط برای طراحی استفاده شود، استفاده از drawWithCache میتواند عملکرد بهتری داشته باشد.
برای مثال، اگر Brush را برای ترسیم گرادیان پشت Text ایجاد کنید، استفاده از
drawWithCache شیء Brush را تا زمانی که اندازه ناحیه ترسیم تغییر کند
ذخیره میکند:
Text( "Hello Compose!", modifier = Modifier .drawWithCache { val brush = Brush.linearGradient( listOf( Color(0xFF9E82F0), Color(0xFF42A5F5) ) ) onDrawBehind { drawRoundRect( brush, cornerRadius = CornerRadius(10.dp.toPx()) ) } } )
اصلاحکنندههای گرافیکی
Modifier.graphicsLayer: اعمال تبدیلها به composables
Modifier.graphicsLayer
اصلاحکنندهای است که باعث میشود محتوای composable در لایه ترسیم کشیده شود. لایه
چند عملکرد مختلف ارائه میدهد، ازجمله:
- جداسازی برای دستورالعملهای ترسیم آن (مشابه
RenderNode). دستورالعملهای ترسیم ضبطشده بهعنوان بخشی از یک لایه میتوانند بهطور کارآمد توسط خط لوله رندرینگ بدون اجرای مجدد کد برنامه دوباره صادر شوند. - تبدیلهایی که برای همه دستورالعملهای طراحی موجود در یک لایه اعمال میشود.
- شطرنجیسازی برای قابلیتهای ترکیببندی. وقتی لایهای شطرنجی میشود، دستورالعملهای ترسیم آن اجرا میشود و خروجی در میانگیر خارج از صفحه ضبط میشود. ترکیببندی چنین میانگیری برای فریمهای بعدی سریعتر از اجرای دستورالعملهای تکی است، اما وقتی تبدیلهایی مثل مقیاسبندی یا چرخش اعمال میشود، بهعنوان نقشه بیتی رفتار خواهد کرد.
تبدیلها
Modifier.graphicsLayer برای دستورالعملهای ترسیم خود جداسازی ارائه میدهد؛
برای مثال، تبدیلهای مختلفی را میتوان بااستفاده از
Modifier.graphicsLayer اعمال کرد. اینها را میتوان بدون نیاز به اجرای مجدد لامبدا طراحی، پویانمایی یا اصلاح کرد.
Modifier.graphicsLayer اندازه یا جای اندازهگیریشده
composable را تغییر نمیدهد، زیرا فقط بر فاز ترسیم تأثیر میگذارد. این یعنی اگر composable شما درنهایت خارج از مرزهای چیدمانش ترسیم شود، ممکن است با composableهای دیگر همپوشانی داشته باشد.
تبدیلهای زیر را میتوان با این اصلاحکننده اعمال کرد:
مقیاس - افزایش اندازه
scaleX و scaleY محتوا را بهترتیب در جهت افقی یا عمودی بزرگ یا کوچک میکند. مقدار 1.0f نشاندهنده عدم تغییر در مقیاس است، مقدار
0.5f یعنی نصف اندازه.
Image( painter = painterResource(id = R.drawable.sunset), contentDescription = "Sunset", modifier = Modifier .graphicsLayer { this.scaleX = 1.2f this.scaleY = 0.8f } )
ترجمه
translationX و translationY را میتوان با graphicsLayer تغییر داد،
translationX composable را به چپ یا راست حرکت میدهد. translationY ترکیبپذیر را بهبالا یا پایین حرکت میدهد.
Image( painter = painterResource(id = R.drawable.sunset), contentDescription = "Sunset", modifier = Modifier .graphicsLayer { this.translationX = 100.dp.toPx() this.translationY = 10.dp.toPx() } )
چرخش
rotationX را برای چرخش افقی، rotationY را برای چرخش عمودی، و
rotationZ را برای چرخش در محور Z (چرخش استاندارد) تنظیم کنید. این مقدار برحسب درجه (۰-۳۶۰) مشخص میشود.
Image( painter = painterResource(id = R.drawable.sunset), contentDescription = "Sunset", modifier = Modifier .graphicsLayer { this.rotationX = 90f this.rotationY = 275f this.rotationZ = 180f } )
مبدأ
transformOrigin را میتوان مشخص کرد. سپس از آن بهعنوان نقطهای استفاده میشود که
تبدیلها از آنجا انجام میشود. همه مثالهای تاکنون از
TransformOrigin.Center استفاده کردهاند که در (0.5f, 0.5f) است. اگر مبدأ را در
(0f, 0f) مشخص کنید، تبدیلها از گوشه بالا سمت چپ
composable شروع میشوند.
اگر مبدأ را با تبدیل rotationZ تغییر دهید، میتوانید ببینید که
مورد حول گوشه بالا سمت چپ composable میچرخد:
Image( painter = painterResource(id = R.drawable.sunset), contentDescription = "Sunset", modifier = Modifier .graphicsLayer { this.transformOrigin = TransformOrigin(0f, 0f) this.rotationX = 90f this.rotationY = 275f this.rotationZ = 180f } )
کلیپ و شکل
شکل، طرح کلیای را مشخص میکند که محتوا هنگام clip = true به آن برش میخورد. در
این مثال، دو جعبه را طوری تنظیم میکنیم که دو کلیپ متفاوت داشته باشند - یکی بااستفاده از
متغیر کلیپ graphicsLayer، و دیگری بااستفاده از پوشش مناسب
Modifier.clip.
Column(modifier = Modifier.padding(16.dp)) { Box( modifier = Modifier .size(200.dp) .graphicsLayer { clip = true shape = CircleShape } .background(Color(0xFFF06292)) ) { Text( "Hello Compose", style = TextStyle(color = Color.Black, fontSize = 46.sp), modifier = Modifier.align(Alignment.Center) ) } Box( modifier = Modifier .size(200.dp) .clip(CircleShape) .background(Color(0xFF4DB6AC)) ) }
محتوای چارگوش اول (نوشتار «Hello Compose») به شکل دایره برش داده میشود:
اگر سپس translationY را به دایره صورتی بالا اعمال کنید، میبینید که مرزهای Composable همچنان یکسان است، اما دایره زیر دایره پایینی (و خارج از مرزهای آن) رسم میشود.
برای برش دادن ترکیبپذیر به منطقهای که در آن ترسیم شده است، میتوانید
Modifier.clip(RectangleShape) دیگری را در ابتدای زنجیره اصلاحکننده اضافه کنید. سپس محتوا
درون مرزهای اصلی باقی میماند.
Column(modifier = Modifier.padding(16.dp)) { Box( modifier = Modifier .clip(RectangleShape) .size(200.dp) .border(2.dp, Color.Black) .graphicsLayer { clip = true shape = CircleShape translationY = 50.dp.toPx() } .background(Color(0xFFF06292)) ) { Text( "Hello Compose", style = TextStyle(color = Color.Black, fontSize = 46.sp), modifier = Modifier.align(Alignment.Center) ) } Box( modifier = Modifier .size(200.dp) .clip(RoundedCornerShape(500.dp)) .background(Color(0xFF4DB6AC)) ) }
آلفا
از Modifier.graphicsLayer میتوان برای تنظیم alpha (کدری) برای کل لایه استفاده کرد. 1.0f کاملاً مات است و 0.0f نامرئی است.
Image( painter = painterResource(id = R.drawable.sunset), contentDescription = "clock", modifier = Modifier .graphicsLayer { this.alpha = 0.5f } )
راهبرد ترکیببندی
کار با آلفا و شفافیت همیشه به سادگی تغییر یک مقدار آلفا نیست. علاوهبر تغییر آلفا،
گزینهای برای تنظیم CompositingStrategy در graphicsLayer نیز وجود دارد. CompositingStrategy تعیین میکند که محتوای ترکیبشدنی چگونه با محتوای دیگری که قبلاً روی صفحهنمایش ترسیم شده است ترکیب (کنار هم قرار داده) شود.
استراتژیهای مختلف عبارتاند از:
خودکار (پیشفرض)
استراتژی ترکیببندی با بقیه پارامترهای graphicsLayer تعیین میشود. اگر آلفا کمتر از 1.0f باشد یا RenderEffect تنظیم شده باشد، لایه را در میانگیر خارج از صفحه رندر میکند. هرگاه آلفا کمتر از 1f باشد، یک لایه ترکیببندی بهطور خودکار ایجاد میشود تا محتوا را رندر کند و سپس این میانگیر خارج از صفحه را با آلفای مربوطه به مقصد بکشد. تنظیم
RenderEffect یا پیمایش بیشازحد همیشه محتوا را در میانگیر خارج از صفحه
صرفنظر از CompositingStrategy تنظیمشده ارائه میکند.
خارج از صفحه
محتوای composable همیشه قبلاز رندر شدن در مقصد، به بافت یا نقشه بیتی خارجاز صفحه شطرنجی میشود. این فرایند برای اعمال کردن عملیات BlendMode به محتوای ماسک و برای بهبود عملکرد هنگام رندر کردن مجموعههای پیچیده از دستورالعملهای طراحی مفید است.
نمونهای از استفاده از CompositingStrategy.Offscreen با BlendModes است.
در مثال زیر، فرض کنید میخواهید بخشهایی از یک Image
ترکیبپذیر را با صدور فرمان ترسیم که از BlendMode.Clear استفاده میکند بردارید. اگر
compositingStrategy را روی CompositingStrategy.Offscreen تنظیم نکنید،
BlendMode با همه محتوای پسزمینه تعامل برقرار میکند.
Image( painter = painterResource(id = R.drawable.dog), contentDescription = "Dog", contentScale = ContentScale.Crop, modifier = Modifier .size(120.dp) .aspectRatio(1f) .background( Brush.linearGradient( listOf( Color(0xFFC5E1A5), Color(0xFF80DEEA) ) ) ) .padding(8.dp) .graphicsLayer { compositingStrategy = CompositingStrategy.Offscreen } .drawWithCache { val path = Path() path.addOval( Rect( topLeft = Offset.Zero, bottomRight = Offset(size.width, size.height) ) ) onDrawWithContent { clipPath(path) { // this draws the actual image - if you don't call drawContent, it wont // render anything this@onDrawWithContent.drawContent() } val dotSize = size.width / 8f // Clip a white border for the content drawCircle( Color.Black, radius = dotSize, center = Offset( x = size.width - dotSize, y = size.height - dotSize ), blendMode = BlendMode.Clear ) // draw the red circle indication drawCircle( Color(0xFFEF5350), radius = dotSize * 0.8f, center = Offset( x = size.width - dotSize, y = size.height - dotSize ) ) } } )
با تنظیم CompositingStrategy روی Offscreen، بافت خارج از صفحهای ایجاد میشود تا فرمانها را اجرا کند (BlendMode فقط روی محتوای این ترکیبشدنی اعمال میشود). سپس آن را روی آنچه قبلاً در صفحه پرداز شده است پرداز میکند، بدون اینکه بر محتوای قبلاً ترسیمشده تأثیر بگذارد.
اگر از CompositingStrategy.Offscreen استفاده نکردهاید، نتایج اعمال
BlendMode.Clear همه پیکسلها را در مقصد پاک میکند، صرفنظر از
آنچه قبلاً تنظیم شده است - بافر رندرینگ پنجره (سیاه)
قابلمشاهده باقی میماند. بسیاری از
BlendModes که شامل آلفا هستند بدون میانگیر
خارجاز صفحه طبق انتظار کار نخواهند کرد. به حلقه سیاه دور نشانگر دایره قرمز توجه کنید:
برای درک بهتر این موضوع: اگر برنامه پسزمینه پنجره نیمهشفافی داشت و شما از CompositingStrategy.Offscreen استفاده نمیکردید، BlendMode با کل برنامه تعامل برقرار میکرد. این کار همه پیکسلها را پاک میکرد تا برنامه یا کاغذدیواری زیرین را نشان دهد، مانند این مثال:
شایان ذکر است که هنگام استفاده از CompositingStrategy.Offscreen، بافت خارج از صفحهای که به اندازه ناحیه طراحی است ایجاد میشود و دوباره روی صفحه رندر میشود. هر فرمان ترسیمی که با این استراتژی انجام میشود، بهطور پیشفرض به این منطقه برش داده میشود. تکهکد زیر تفاوتها را هنگام جابهجایی به استفاده از بافتهای خارج از صفحه نشان میدهد:
@Composable fun CompositingStrategyExamples() { Column( modifier = Modifier .fillMaxSize() .wrapContentSize(Alignment.Center) ) { // Does not clip content even with a graphics layer usage here. By default, graphicsLayer // does not allocate + rasterize content into a separate layer but instead is used // for isolation. That is draw invalidations made outside of this graphicsLayer will not // re-record the drawing instructions in this composable as they have not changed Canvas( modifier = Modifier .graphicsLayer() .size(100.dp) // Note size of 100 dp here .border(2.dp, color = Color.Blue) ) { // ... and drawing a size of 200 dp here outside the bounds drawRect(color = Color.Magenta, size = Size(200.dp.toPx(), 200.dp.toPx())) } Spacer(modifier = Modifier.size(300.dp)) /* Clips content as alpha usage here creates an offscreen buffer to rasterize content into first then draws to the original destination */ Canvas( modifier = Modifier // force to an offscreen buffer .graphicsLayer(compositingStrategy = CompositingStrategy.Offscreen) .size(100.dp) // Note size of 100 dp here .border(2.dp, color = Color.Blue) ) { /* ... and drawing a size of 200 dp. However, because of the CompositingStrategy.Offscreen usage above, the content gets clipped */ drawRect(color = Color.Red, size = Size(200.dp.toPx(), 200.dp.toPx())) } } }
ModulateAlpha
این استراتژی ترکیببندی آلفا را برای هریک از دستورالعملهای طراحی ضبطشده در graphicsLayer تعدیل میکند. اگر RenderEffect تنظیم نشده باشد، میانگیر خارج از صفحه برای آلفای کمتر از ۱٫۰f ایجاد نمیکند، بنابراین میتواند برای پردازش آلفا کارآمدتر باشد. اما ممکن است برای محتوای همپوشان نتایج متفاوتی ارائه دهد. برای موارد استفادهای که ازقبل مشخص است
محتوا همپوشانی ندارد، این روش میتواند عملکرد بهتری نسبتبه
CompositingStrategy.Auto با مقادیر آلفای کمتر از ۱ ارائه دهد.
مثال زیر استراتژیهای مختلف ترکیببندی را نشان میدهد - اعمال
آلفاهای مختلف به بخشهای مختلف ترکیبشدنیها، و اعمال
استراتژی Modulate:
@Preview @Composable fun CompositingStrategy_ModulateAlpha() { Column( modifier = Modifier .fillMaxSize() .padding(32.dp) ) { // Base drawing, no alpha applied Canvas( modifier = Modifier.size(200.dp) ) { drawSquares() } Spacer(modifier = Modifier.size(36.dp)) // Alpha 0.5f applied to whole composable Canvas( modifier = Modifier .size(200.dp) .graphicsLayer { alpha = 0.5f } ) { drawSquares() } Spacer(modifier = Modifier.size(36.dp)) // 0.75f alpha applied to each draw call when using ModulateAlpha Canvas( modifier = Modifier .size(200.dp) .graphicsLayer { compositingStrategy = CompositingStrategy.ModulateAlpha alpha = 0.75f } ) { drawSquares() } } } private fun DrawScope.drawSquares() { val size = Size(100.dp.toPx(), 100.dp.toPx()) drawRect(color = Red, size = size) drawRect( color = Purple, size = size, topLeft = Offset(size.width / 4f, size.height / 4f) ) drawRect( color = Yellow, size = size, topLeft = Offset(size.width / 4f * 2f, size.height / 4f * 2f) ) } @Preview @Composable fun ModifierGraphicsLayerOutsets() { Column( modifier = Modifier .background(Color(0xFF0A0E14)) .padding(48.dp), verticalArrangement = Arrangement.spacedBy(48.dp), horizontalAlignment = Alignment.CenterHorizontally ) { val pillShape = RoundedCornerShape(percent = 50) // Without outsets: alpha = 0.5f creates an offscreen buffer that clips the 24.dp glow Box( modifier = Modifier .size( width = 140.dp, height = 56.dp ) .graphicsLayer( alpha = 0.5f, clip = false ) .dropShadow( shape = pillShape, shadow = Shadow(radius = 24.dp, color = Color.Cyan) ) .background(color = Color(0xFF141824), shape = pillShape), contentAlignment = Alignment.Center ) { Text( text = "✨ Glow", color = Color.White, fontSize = 18.sp ) } Box( modifier = Modifier .size( width = 140.dp, height = 56.dp ) .graphicsLayer( alpha = 0.5f, outsets = LayerOutsets(24.dp), clip = false ) .dropShadow( shape = pillShape, shadow = Shadow(radius = 24.dp, color = Color.Cyan) ) .background(color = Color(0xFF141824), shape = pillShape), contentAlignment = Alignment.Center ) { Text( text = "✨ Glow", color = Color.White, fontSize = 18.sp ) } } } val Purple = Color(0xFF7E57C2) val Yellow = Color(0xFFFFCA28) val Red = Color(0xFFEF5350)
بیرونزدگیهای لایه
وقتی یک composable در میانگیر خارج از صفحه کشیده میشود (برای مثال، وقتی alpha
کمتر از 1.0f باشد، RenderEffect تنظیم شده باشد، یا از CompositingStrategy.Offscreen
استفاده شود)، بافت خارج از صفحه بهطور پیشفرض به مرزهای چیدمان اندازهگیریشده composable تبدیل میشود. هرگونه طراحی یا سایه درون لایه که فراتر از مرزهای چیدمان ترکیبپذیر گسترش یابد (مانند درخشش بیرونی که با Modifier.dropShadow رسم شده است) بهطور ضمنی در مرز میانگیر خارج از صفحه بریده میشود.
بهجای افزودن Modifier.padding() (که اندازهگیری چیدمان عناصر میانای کاربر مجاور را تغییر میدهد)، LayerOutsets را به پارامتر outsets از Modifier.graphicsLayer ارسال کنید. این کار مرزهای دیداری میانگیر خارج از صفحه را در هر طرف گسترش میدهد، بدون اینکه اندازه چیدمان اندازهگیریشده ترکیبپذیر را تغییر دهد. توجه داشته باشید که
LayerOutsets شکل برش لایه یا حدود سایه را گسترش نمیدهد، که
براساس اندازه اندازهگیریشده اصلی ترکیبپذیر باقی میماند (بنابراین clip = false را روی graphicsLayer نگه دارید تا از برش به حدود اصلی جلوگیری شود):
Box( modifier = Modifier .size( width = 140.dp, height = 56.dp ) .graphicsLayer( alpha = 0.5f, outsets = LayerOutsets(24.dp), clip = false ) .dropShadow( shape = pillShape, shadow = Shadow(radius = 24.dp, color = Color.Cyan) ) .background(color = Color(0xFF141824), shape = pillShape), contentAlignment = Alignment.Center ) { Text( text = "✨ Glow", color = Color.White, fontSize = 18.sp ) }
LayerOutsets (بالا، برشخورده در مرزهای چیدمان مستطیلی ترکیبپذیر) درمقابل با LayerOutsets(24.dp) (پایین، برشنخورده)نوشتن محتوای یک composable در یک bitmap
یک مورد استفاده رایج، ایجاد Bitmap از یک composable است. برای کپی کردن
محتوای ترکیبپذیرتان در Bitmap، بااستفاده از
rememberGraphicsLayer()، GraphicsLayer ایجاد کنید.
بااستفاده از drawWithContent() و graphicsLayer.record{}، فرمانهای طراحی را به لایه جدید هدایت کنید. سپس لایه را در بوم نمایان بااستفاده از
drawLayer بکشید:
val coroutineScope = rememberCoroutineScope() val graphicsLayer = rememberGraphicsLayer() Box( modifier = Modifier .drawWithContent { // call record to capture the content in the graphics layer graphicsLayer.record { // draw the contents of the composable into the graphics layer this@drawWithContent.drawContent() } // draw the graphics layer on the visible canvas drawLayer(graphicsLayer) } .clickable { coroutineScope.launch { val bitmap = graphicsLayer.toImageBitmap() // do something with the newly acquired bitmap } } .background(Color.White) ) { Text("Hello Android", fontSize = 26.sp) }
میتوانید نقشه بیتی را در دیسک ذخیره کنید و آن را همرسانی کنید. برای جزئیات بیشتر، قطعه کد نمونه کامل را ببینید. حتماً قبلاز تلاش برای ذخیره کردن در دیسک، اجازههای روی دستگاه را بررسی کنید.
اصلاحگر طراحی سفارشی
برای ایجاد اصلاحکننده سفارشی خودتان، میانای DrawModifier را پیادهسازی کنید. این کار
به شما امکان میدهد به ContentDrawScope دسترسی پیدا کنید، که همان چیزی است که
هنگام استفاده از Modifier.drawWithContent() درمعرض دید قرار میگیرد. سپس میتوانید عملیاتهای رایج طراحی را به اصلاحکنندههای طراحی سفارشی استخراج کنید تا کد را پاکسازی کنید و پوشانندههای مناسبی ارائه دهید؛ برای مثال، Modifier.background() یک DrawModifier مناسب است.
برای مثال، اگر میخواهید Modifier را پیادهسازی کنید که محتوا را بهصورت عمودی برمیگرداند،
میتوانید یکی را بهصورت زیر ایجاد کنید:
class FlippedModifier : DrawModifier { override fun ContentDrawScope.draw() { scale(1f, -1f) { this@draw.drawContent() } } } fun Modifier.flipped() = this.then(FlippedModifier())
سپس از این اصلاحکننده معکوسشده که روی Text اعمال شده است استفاده کنید:
Text( "Hello Compose!", modifier = Modifier .flipped() )
منابع بیشتر
برای مثالهای بیشتر درباره استفاده از graphicsLayer و طراحی سفارشی، منابع زیر را بررسی کنید:
توصیهشده برای شما
- توجه: وقتی جاوا اسکریپت خاموش باشد، نوشتار پیوند نمایش داده میشود
- گرافیک در Compose
- سفارشیسازی تصویر {:#customize-image}
- Kotlin برای Jetpack Compose