اصلاح کننده ها به شما این امکان را می دهند که یک ترکیب بندی را تزئین یا تقویت کنید. اصلاحکنندهها به شما اجازه میدهند این نوع کارها را انجام دهید:
- اندازه، چیدمان، رفتار و ظاهر کامپوزیشن را تغییر دهید
- اطلاعاتی مانند برچسبهای دسترسپذیری را اضافه کنید
- پردازش ورودی کاربر
- فعل و انفعالات سطح بالا را اضافه کنید، مانند ایجاد یک عنصر قابل کلیک، قابل پیمایش، کشیدن، یا بزرگنمایی
اصلاح کننده ها اشیاء استاندارد Kotlin هستند. با فراخوانی یکی از توابع کلاس Modifier
یک اصلاح کننده ایجاد کنید:
@Composable private fun Greeting(name: String) { Column(modifier = Modifier.padding(24.dp)) { Text(text = "Hello,") Text(text = name) } }
شما می توانید این توابع را به هم متصل کنید تا آنها را ترکیب کنید:
@Composable private fun Greeting(name: String) { Column( modifier = Modifier .padding(24.dp) .fillMaxWidth() ) { Text(text = "Hello,") Text(text = name) } }
در کد بالا، به توابع مختلف اصلاح کننده توجه کنید که با هم استفاده می شوند.
-
padding
فضایی را در اطراف یک عنصر قرار می دهد. -
fillMaxWidth
باعث میشود که composable حداکثر عرضی که از والد به آن داده شده را پر کند.
بهترین روش این است که همه اجزای سازنده شما یک پارامتر modifier
را بپذیرند و آن اصلاحکننده را به اولین فرزند خود که UI منتشر میکند، ارسال کنید. انجام این کار کد شما را قابل استفاده مجدد تر می کند و رفتار آن را قابل پیش بینی تر و شهودی می کند. برای اطلاعات بیشتر، به دستورالعملهای Compose API مراجعه کنید، عناصر یک پارامتر Modifier را میپذیرند و رعایت میکنند .
ترتیب اصلاح کننده ها مهم است
ترتیب توابع اصلاح کننده قابل توجه است. از آنجایی که هر تابع تغییراتی را در Modifier
برگردانده شده توسط تابع قبلی ایجاد می کند، دنباله روی نتیجه نهایی تأثیر می گذارد. بیایید نمونه ای از این را ببینیم:
@Composable fun ArtistCard(/*...*/) { val padding = 16.dp Column( Modifier .clickable(onClick = onClick) .padding(padding) .fillMaxWidth() ) { // rest of the implementation } }
در کد بالا کل ناحیه قابل کلیک است، از جمله padding اطراف، زیرا اصلاح کننده padding
بعد از اصلاح کننده clickable
اعمال شده است. اگر ترتیب اصلاحکنندهها معکوس شود، فضای اضافه شده با padding
به ورودی کاربر واکنش نشان نمیدهد:
@Composable fun ArtistCard(/*...*/) { val padding = 16.dp Column( Modifier .padding(padding) .clickable(onClick = onClick) .fillMaxWidth() ) { // rest of the implementation } }
اصلاح کننده های داخلی
Jetpack Compose فهرستی از اصلاحکنندههای داخلی را ارائه میکند تا به شما کمک کند یک ترکیبسازی را تزئین یا تقویت کنید. در اینجا برخی از اصلاحکنندههای رایج وجود دارد که از آنها برای تنظیم طرحبندیهای خود استفاده میکنید.
padding
و size
بهطور پیشفرض، طرحبندیهای ارائهشده در «نوشتن»، فرزندانشان را میپیچاند. با این حال، می توانید با استفاده از اصلاح کننده size
، یک اندازه را تنظیم کنید:
@Composable fun ArtistCard(/*...*/) { Row( modifier = Modifier.size(width = 400.dp, height = 100.dp) ) { Image(/*...*/) Column { /*...*/ } } }
توجه داشته باشید که اندازه ای که شما مشخص کرده اید در صورتی که محدودیت های والد طرح را برآورده نکند، ممکن است رعایت نشود. اگر میخواهید اندازه قابل ترکیب بدون توجه به محدودیتهای ورودی ثابت شود، از اصلاحکننده requiredSize
استفاده کنید:
@Composable fun ArtistCard(/*...*/) { Row( modifier = Modifier.size(width = 400.dp, height = 100.dp) ) { Image( /*...*/ modifier = Modifier.requiredSize(150.dp) ) Column { /*...*/ } } }
در این مثال، حتی با تنظیم height
والد روی 100.dp
، ارتفاع Image
150.dp
خواهد بود، زیرا اصلاحکننده requiredSize
اولویت دارد.
اگر میخواهید طرحبندی فرزند تمام ارتفاع مجاز مجاز توسط والدین را پر کند، اصلاحکننده fillMaxHeight
را اضافه کنید (Compose همچنین fillMaxSize
و fillMaxWidth
را ارائه میکند):
@Composable fun ArtistCard(/*...*/) { Row( modifier = Modifier.size(width = 400.dp, height = 100.dp) ) { Image( /*...*/ modifier = Modifier.fillMaxHeight() ) Column { /*...*/ } } }
برای اضافه کردن padding در اطراف یک عنصر، یک اصلاح کننده padding
تنظیم کنید.
اگر می خواهید padding را بالای خط مبنا متن اضافه کنید به طوری که به فاصله مشخصی از بالای طرح تا خط مبنا برسید، از اصلاح کننده paddingFromBaseline
استفاده کنید:
@Composable fun ArtistCard(artist: Artist) { Row(/*...*/) { Column { Text( text = artist.name, modifier = Modifier.paddingFromBaseline(top = 50.dp) ) Text(artist.lastSeenOnline) } } }
افست
برای قرار دادن یک طرح نسبت به موقعیت اصلی آن، اصلاح کننده offset
را اضافه کنید و افست را در محور x و y تنظیم کنید. افست می تواند مثبت و همچنین غیر مثبت باشد. تفاوت بین padding
و offset
در این است که افزودن یک offset
به یک composable اندازه گیری آن را تغییر نمی دهد:
@Composable fun ArtistCard(artist: Artist) { Row(/*...*/) { Column { Text(artist.name) Text( text = artist.lastSeenOnline, modifier = Modifier.offset(x = 4.dp) ) } } }
اصلاح کننده offset
به صورت افقی با توجه به جهت طرح اعمال می شود. در زمینه چپ به راست ، یک offset
مثبت عنصر را به راست منتقل می کند، در حالی که در زمینه راست به چپ ، عنصر را به چپ منتقل می کند. اگر نیاز به تنظیم افست بدون در نظر گرفتن جهت طرح دارید، به اصلاح کننده absoluteOffset
مراجعه کنید، که در آن مقدار افست مثبت همیشه عنصر را به سمت راست منتقل می کند.
تعدیل کننده offset
دو بار اضافه را ارائه می دهد - offset
که آفست ها را به عنوان پارامتر می گیرد و offset
که یک لامبدا را می گیرد. برای اطلاعات عمیق تر در مورد زمان استفاده از هر یک از این موارد و نحوه بهینه سازی عملکرد، بخش Compose performance - Defer reads را تا زمانی که ممکن است بخوانید.
ایمنی محدوده در Compose
در Compose، اصلاحکنندههایی وجود دارد که فقط زمانی میتوان از آنها استفاده کرد که برای فرزندان برخی از اجزای سازنده خاص اعمال شوند. نوشتن این مورد را با استفاده از محدوده های سفارشی اعمال می کند.
به عنوان مثال، اگر میخواهید کودکی را به بزرگی Box
والد بدون تأثیر بر اندازه Box
بسازید، از اصلاح کننده matchParentSize
استفاده کنید. matchParentSize
فقط در BoxScope
موجود است. بنابراین، آن را فقط می توان بر روی یک فرزند در والد Box
استفاده کرد.
ایمنی Scope شما را از اضافه کردن اصلاحکنندههایی که در سایر اجزای سازنده و محدودهها کار نمیکنند جلوگیری میکند و باعث صرفهجویی در زمان از آزمون و خطا میشود.
اصلاحکنندههای محدوده، اطلاعاتی را که والدین باید درباره کودک بدانند، به والدین اطلاع میدهند. اینها معمولاً به عنوان اصلاح کننده های داده والد نیز شناخته می شوند. داخلی آنها با اصلاح کننده های هدف کلی متفاوت است، اما از منظر استفاده، این تفاوت ها اهمیتی ندارند.
matchParentSize
در Box
همانطور که در بالا ذکر شد، اگر می خواهید طرح فرزند به اندازه یک Box
والد باشد بدون اینکه بر اندازه Box
تأثیر بگذارد، از اصلاح کننده matchParentSize
استفاده کنید.
توجه داشته باشید که matchParentSize
فقط در محدوده Box
در دسترس است، به این معنی که فقط برای فرزندان مستقیم Box
composable اعمال می شود.
در مثال زیر، فرزند Spacer
اندازه خود را از Box
والد خود می گیرد، که به نوبه خود اندازه خود را از بزرگترین فرزندان، ArtistCard
در این مورد می گیرد.
@Composable fun MatchParentSizeComposable() { Box { Spacer( Modifier .matchParentSize() .background(Color.LightGray) ) ArtistCard() } }
اگر از fillMaxSize
به جای matchParentSize
استفاده می شد، Spacer
تمام فضای موجود مجاز را به والد می برد و به نوبه خود باعث می شود والد گسترش یابد و تمام فضای موجود را پر کند.
weight
در Row
و Column
همانطور که در بخش قبلی در مورد Padding and size مشاهده کردید، به طور پیشفرض، اندازه قابل ترکیب با محتوایی که در آن قرار میگیرد تعریف میشود. میتوانید با استفاده از weight
اصلاحکننده که فقط در RowScope
و ColumnScope
موجود است، یک اندازه قابل تنظیم را تنظیم کنید تا در والد آن انعطافپذیر باشد.
بیایید Row
بگیریم که شامل دو Box
composable است. وزن جعبه اول دو برابر weight
دوم است، بنابراین عرض آن دو برابر است. از آنجایی که عرض Row
210.dp
است، Box
اول 140.dp
عرض دارد و دومی 70.dp
است.
@Composable fun ArtistCard(/*...*/) { Row( modifier = Modifier.fillMaxWidth() ) { Image( /*...*/ modifier = Modifier.weight(2f) ) Column( modifier = Modifier.weight(1f) ) { /*...*/ } } }
استخراج و استفاده مجدد از اصلاح کننده ها
چندین اصلاح کننده را می توان برای تزئین یا تقویت یک ترکیب بندی به هم متصل کرد. این زنجیره از طریق رابط Modifier
ایجاد می شود که نشان دهنده یک لیست مرتب و غیرقابل تغییر از تک Modifier.Elements
است.
هر Modifier.Element
نشان دهنده یک رفتار فردی است، مانند رفتارهای چیدمان، طراحی و گرافیک، همه رفتارهای مربوط به اشاره، تمرکز و معناشناسی، و همچنین رویدادهای ورودی دستگاه. موارد سفارش آنها: عناصر اصلاح کننده که ابتدا اضافه می شوند ابتدا اعمال می شوند.
گاهی اوقات استفاده مجدد از نمونههای زنجیره اصلاحکننده یکسان در ترکیبپذیرهای متعدد، با استخراج آنها در متغیرها و بالا بردن آنها در محدودههای بالاتر، میتواند مفید باشد. به چند دلیل می تواند خوانایی کد را بهبود بخشد یا به بهبود عملکرد برنامه شما کمک کند:
- تخصیص مجدد اصلاحکنندهها زمانی که ترکیب مجدد برای ترکیبهایی که از آنها استفاده میکنند رخ دهد، تکرار نمیشود.
- زنجیرههای اصلاحکننده به طور بالقوه میتوانند بسیار طولانی و پیچیده باشند، بنابراین استفاده مجدد از همان نمونهای از یک زنجیره میتواند حجم کاری را که زمان اجرا نوشتن هنگام مقایسه آنها انجام میشود کاهش دهد.
- این استخراج پاکیزگی، سازگاری و نگهداری کد را در سراسر پایگاه کد ارتقا می دهد
بهترین روش ها برای استفاده مجدد از اصلاح کننده ها
زنجیره های Modifier
خود را ایجاد کنید و آنها را استخراج کنید تا از آنها در چندین مؤلفه قابل ترکیب استفاده مجدد کنید. صرفاً ذخیره یک اصلاح کننده کاملاً خوب است، زیرا آنها اشیاء داده مانند هستند:
val reusableModifier = Modifier .fillMaxWidth() .background(Color.Red) .padding(12.dp)
استخراج و استفاده مجدد از اصلاح کننده ها هنگام مشاهده حالت تغییر مکرر
هنگام مشاهده حالتهای تغییر مکرر در داخل اجزای سازنده، مانند حالتهای انیمیشن یا scrollState
، میتوان مقدار قابل توجهی از ترکیب مجدد انجام شود. در این حالت، اصلاحکنندههای شما در هر ترکیب مجدد و به طور بالقوه برای هر فریم تخصیص داده میشوند:
@Composable fun LoadingWheelAnimation() { val animatedState = animateFloatAsState(/*...*/) LoadingWheel( // Creation and allocation of this modifier will happen on every frame of the animation! modifier = Modifier .padding(12.dp) .background(Color.Gray), animatedState = animatedState ) }
در عوض، میتوانید همان نمونه اصلاحکننده را ایجاد، استخراج و دوباره استفاده کنید و آن را به composable ارسال کنید:
// Now, the allocation of the modifier happens here: val reusableModifier = Modifier .padding(12.dp) .background(Color.Gray) @Composable fun LoadingWheelAnimation() { val animatedState = animateFloatAsState(/*...*/) LoadingWheel( // No allocation, as we're just reusing the same instance modifier = reusableModifier, animatedState = animatedState ) }
استخراج و استفاده مجدد از اصلاح کننده های بدون اسکوپ
اصلاحکنندهها را میتوان بدون اسکوپ یا محدوده به یک ترکیببندی خاص تغییر داد. در مورد اصلاحکنندههای بدون اسکوپ، میتوانید به راحتی آنها را خارج از هر ترکیبسازی بهعنوان متغیرهای ساده استخراج کنید:
val reusableModifier = Modifier .fillMaxWidth() .background(Color.Red) .padding(12.dp) @Composable fun AuthorField() { HeaderText( // ... modifier = reusableModifier ) SubtitleText( // ... modifier = reusableModifier ) }
این می تواند به ویژه هنگامی که با طرح بندی Lazy ترکیب شود مفید باشد. در بیشتر موارد، شما میخواهید که همه موارد، بالقوه قابل توجه، دارای اصلاحکنندههای مشابه باشند:
val reusableItemModifier = Modifier .padding(bottom = 12.dp) .size(216.dp) .clip(CircleShape) @Composable private fun AuthorList(authors: List<Author>) { LazyColumn { items(authors) { AsyncImage( // ... modifier = reusableItemModifier, ) } } }
استخراج و استفاده مجدد از اصلاح کننده های محدوده
هنگامی که با اصلاحکنندههایی سروکار دارید که در محدوده خاصی از ترکیبپذیر هستند، میتوانید آنها را تا بالاترین سطح ممکن استخراج کنید و در صورت لزوم مجدداً استفاده کنید:
Column(/*...*/) { val reusableItemModifier = Modifier .padding(bottom = 12.dp) // Align Modifier.Element requires a ColumnScope .align(Alignment.CenterHorizontally) .weight(1f) Text1( modifier = reusableItemModifier, // ... ) Text2( modifier = reusableItemModifier // ... ) // ... }
شما فقط باید اصلاحکنندههای استخراجشده با محدوده را به کودکان مستقیم با همان محدوده ارسال کنید. برای ارجاع بیشتر در مورد اینکه چرا این مهم است، بخش ایمنی محدوده در نوشتن را ببینید:
Column(modifier = Modifier.fillMaxWidth()) { // Weight modifier is scoped to the Column composable val reusableItemModifier = Modifier.weight(1f) // Weight will be properly assigned here since this Text is a direct child of Column Text1( modifier = reusableItemModifier // ... ) Box { Text2( // Weight won't do anything here since the Text composable is not a direct child of Column modifier = reusableItemModifier // ... ) } }
زنجیره ای بیشتر از اصلاح کننده های استخراج شده
میتوانید با فراخوانی تابع .then()
زنجیرههای اصلاحکننده استخراجشده خود را زنجیرهبندی یا اضافه کنید:
val reusableModifier = Modifier .fillMaxWidth() .background(Color.Red) .padding(12.dp) // Append to your reusableModifier reusableModifier.clickable { /*...*/ } // Append your reusableModifier otherModifier.then(reusableModifier)
فقط به خاطر داشته باشید که ترتیب اصلاح کننده ها مهم است!
بیشتر بدانید
ما لیست کاملی از اصلاح کننده ها را با پارامترها و دامنه آنها ارائه می دهیم.
برای تمرین بیشتر در مورد نحوه استفاده از اصلاحکنندهها، میتوانید طرحبندیهای پایه را در Compose codelab نیز مرور کنید یا به مخزن Now in Android مراجعه کنید.
برای اطلاعات بیشتر در مورد اصلاحکنندههای سفارشی و نحوه ایجاد آنها، نگاهی به مستندات طرحبندیهای سفارشی بیاندازید - با استفاده از اصلاحکننده طرح .
{% کلمه به کلمه %}برای شما توصیه می شود
- توجه: وقتی جاوا اسکریپت خاموش است، متن پیوند نمایش داده می شود
- اصول چیدمان را بنویسید
- اقدامات ویرایشگر {:#editor-actions}
- طرحبندیهای سفارشی {:#custom-layouts }