ترتیب اصلاح‌گر و محدودیت

در Compose، می‌توانید چندین اصلاح‌گر را به‌هم زنجیر کنید تا ظاهر و احساس یک composable را تغییر دهید. این زنجیره‌های اصلاح‌کننده می‌توانند بر محدودیت‌های ارسال‌شده به ترکیب‌پذیرها تأثیر بگذارند، که مرزهای عرض و ارتفاع را تعریف می‌کنند.

این صفحه توضیح می‌دهد که چگونه اصلاح‌کننده‌های زنجیره‌ای بر محدودیت‌ها و به‌نوبه خود بر اندازه‌گیری و جای‌گذاری عناصر قابل‌ترکیب تأثیر می‌گذارند.

اصلاح‌گرها در درخت واسط کاربر

برای درک نحوه تأثیر اصلاح‌کننده‌ها بر یکدیگر، مفید است که نحوه ظاهر شدن آن‌ها را در درخت UI که درطول فاز ترکیب‌بندی تولید می‌شود، تجسم کنید. برای اطلاعات بیشتر، به بخش ترکیب‌بندی مراجعه کنید.

در درخت واسط کاربر، می‌توانید اصلاح‌کننده‌ها را به‌عنوان گره‌های پوشاننده برای گره‌های چیدمان تجسم کنید:

کد برای ترکیب‌پذیرها و اصلاح‌کننده‌ها، و نمایش دیداری آن‌ها به‌عنوان درخت میانای کاربر.
شکل ۱. تغییردهنده‌هایی که گره‌های چیدمان را در درخت واسط کاربر می‌پیچند.

افزودن بیش‌از یک اصلاح‌گر به یک composable زنجیره‌ای از اصلاح‌گرها ایجاد می‌کند. وقتی چند اصلاح‌کننده را زنجیره‌ای می‌کنید، هر گره اصلاح‌کننده بقیه زنجیره و گره چیدمان داخل آن را دربرمی‌گیرد. برای مثال، وقتی اصلاح‌کننده clip و size را زنجیره‌ای می‌کنید، گره اصلاح‌کننده clip گره اصلاح‌کننده size را دربرمی‌گیرد، که سپس گره چیدمان Image را دربرمی‌گیرد.

در فاز چیدمان، الگوریتمی که درخت را پیمایش می‌کند ثابت می‌ماند، اما هر گره اصلاح‌گر نیز بازدید می‌شود. به این ترتیب، یک اصلاح‌کننده می‌تواند الزامات اندازه و قرارگیری اصلاح‌کننده یا گره چیدمانی را که می‌پیچد تغییر دهد.

همان‌طور که در شکل ۲ نشان داده شده است، پیاده‌سازی ترکیب‌پذیرهای Image و Text خود شامل زنجیره‌ای از اصلاح‌کننده‌ها است که یک گره چیدمان واحد را دربرمی‌گیرد.

پیاده‌سازی‌های Row و Column گره‌های چیدمانی هستند که نحوه چیدمان فرزندانشان را توصیف می‌کنند.

ساختار درختی قبلی، اما اکنون هر گره فقط یک چیدمان ساده است، با تعداد زیادی گره اصلاح‌کننده که آن را احاطه کرده‌اند.
شکل ۲. همان ساختار درختی شکل ۱، اما با ترکیب‌پذیرها در درخت رابط کاربری که به‌صورت زنجیره‌های اصلاح‌کننده تجسم شده‌اند.

به‌طور خلاصه:

  • تغییردهنده‌ها یک تغییردهنده یا گره چیدمان را می‌پوشانند.
  • گره‌های چیدمان می‌توانند چندین گره فرزند را چیدمان کنند.

بخش‌های زیر نحوه استفاده از این مدل ذهنی را برای استدلال درباره زنجیره‌سازی اصلاح‌کننده‌ها و نحوه تأثیر آن بر اندازه composableها شرح می‌دهند.

محدودیت‌ها در مرحله چیدمان

فاز چیدمان از یک الگوریتم سه‌مرحله‌ای برای یافتن عرض، ارتفاع، و مختصات x و y هر گره چیدمان پیروی می‌کند:

  1. اندازه‌گیری فرزندان: گره فرزندان خود را (درصورت وجود) اندازه‌گیری می‌کند.
  2. تصمیم‌گیری درباره اندازه خود: براساس آن اندازه‌گیری‌ها، گره درباره اندازه خود تصمیم می‌گیرد.
  3. قرار دادن فرزندان: هر گره فرزند نسبت به موقعیت خود گره قرار می‌گیرد.

Constraints به پیدا کردن اندازه مناسب برای گره‌ها درطول دو مرحله اول الگوریتم کمک می‌کند. محدودیت‌ها مرزهای حداقل و حداکثر را برای عرض و ارتفاع گره تعریف می‌کنند. وقتی گره درباره اندازه‌اش تصمیم می‌گیرد، اندازه اندازه‌گیری‌شده آن باید در این محدوده اندازه قرار بگیرد.

انواع محدودیت‌ها

محدودیت می‌تواند یکی از موارد زیر باشد:

  • محدود: گره دارای حداکثر و حداقل عرض و ارتفاع است.
محدودیت‌های مرزدار با اندازه‌های مختلف در یک محفظه.
شکل ۳. محدودیت‌های مرزی.
  • نامحدود: گره به هیچ اندازه‌ای محدود نیست. حداکثر عرض و ارتفاع روی بی‌نهایت تنظیم شده است.
محدودیت‌های نامحدودی که عرض و ارتفاع آن‌ها روی بی‌نهایت تنظیم شده است. محدودیت‌ها فراتر از ظرف گسترش می‌یابند.
شکل ۴. محدودیت‌های نامحدود.
  • دقیق: از گره خواسته می‌شود از یک الزام اندازه دقیق پیروی کند. حدود کمینه و بیشینه روی مقدار یکسانی تنظیم شده است.
محدودیت‌های دقیق که با الزام اندازه دقیق در محفظه مطابقت دارد.
شکل ۵. محدودیت‌های دقیق.
  • ترکیب: گره از ترکیبی از انواع محدودیت‌های قبلی پیروی می‌کند. برای مثال، یک قید می‌تواند عرض را محدود کند درحالی‌که اجازه می‌دهد حداکثر ارتفاع نامحدود باشد، یا عرض دقیقی را تنظیم کند اما ارتفاع محدودی را ارائه دهد.
دو محفظه که ترکیبی از محدودیت‌های محدود و نامحدود و عرض و ارتفاع دقیق را نشان می‌دهند.
شکل ۶. ترکیب محدودیت‌های محدود و نامحدود و عرض و ارتفاع دقیق.

بخش بعدی توضیح می‌دهد که چگونه این محدودیت‌ها از والد به فرزند منتقل می‌شوند.

نحوه انتقال محدودیت‌ها از والد به فرزند

درطول اولین مرحله از الگوریتم شرح‌داده‌شده در محدودیت‌ها در فاز چیدمان، محدودیت‌ها از والد به فرزند در درخت واسط کاربر منتقل می‌شوند.

وقتی گره والد فرزندانش را اندازه‌گیری می‌کند، این محدودیت‌ها را برای هر فرزند فراهم می‌کند تا به آن‌ها اطلاع دهد که چقدر بزرگ یا کوچک می‌توانند باشند. سپس، وقتی اندازه خود را تعیین می‌کند، از محدودیت‌هایی که توسط والدینش منتقل شده‌اند نیز پیروی می‌کند.

در سطح بالا، الگوریتم به روش زیر کار می‌کند:

  1. برای تصمیم‌گیری درباره اندازه‌ای که واقعاً می‌خواهد اشغال کند، گره ریشه در درخت واسط کاربر فرزندانش را اندازه‌گیری می‌کند و همان محدودیت‌ها را به اولین فرزندش ارسال می‌کند.
  2. اگر فرزند اصلاح‌کننده‌ای باشد که بر اندازه‌گیری تأثیر نمی‌گذارد، محدودیت‌ها را به اصلاح‌کننده بعدی ارسال می‌کند. محدودیت‌ها همان‌طور که هستند به زنجیره اصلاح‌کننده منتقل می‌شوند، مگراینکه به اصلاح‌کننده‌ای برسیم که بر اندازه‌گیری تأثیر بگذارد. سپس اندازه محدودیت‌ها براساس آن تغییر می‌کند.
  3. وقتی به گرهی برسد که هیچ فرزند ندارد (به آن «گره برگ» می‌گویند)، اندازه خود را براساس محدودیت‌های ارسال‌شده تعیین می‌کند و این اندازه حل‌شده را به والد خود برمی‌گرداند.
  4. والد محدودیت‌هایش را براساس اندازه‌های این فرزند تطبیق می‌دهد و فرزند بعدی‌اش را با این محدودیت‌های اصلاح‌شده فراخوانی می‌کند.
  5. وقتی همه فرزندان یک والد اندازه‌گیری شدند، گره والد درباره اندازه خودش تصمیم می‌گیرد و آن را به والد خودش اطلاع می‌دهد.
  6. به این ترتیب، کل درخت به‌صورت عمق-نخست پیمایش می‌شود. درنهایت، همه گره‌ها اندازه خود را تعیین می‌کنند و مرحله اندازه‌گیری تکمیل می‌شود.

برای مشاهده مثالی دقیق، ویدیو ترتیب اصلاح‌کننده‌ها و محدودیت‌ها را ببینید.

اصلاح‌کننده‌هایی که بر محدودیت‌ها تأثیر می‌گذارند

در بخش قبلی یاد گرفتید که برخی‌از اصلاح‌کننده‌ها می‌توانند بر اندازه قید تأثیر بگذارند. بخش‌های زیر اصلاح‌کننده‌های خاصی را که بر محدودیت‌ها تأثیر می‌گذارند شرح می‌دهند.

اصلاح‌گر size

اصلاح‌کننده size اندازه ترجیحی محتوا را اعلام می‌کند.

برای مثال، درخت UI زیر باید در محفظه‌ای با ابعاد 300dp در 200dp ارائه شود. محدودیت‌ها محدود هستند و عرض‌های بین 100dp و 300dp و ارتفاع‌های بین 100dp و 200dp را مجاز می‌کنند:

بخشی از درخت میانای کاربری با اصلاح‌کننده اندازه که گره چیدمان را دربرمی‌گیرد، و نمایش محدودیت‌های مرزدار تنظیم‌شده توسط اصلاح‌کننده اندازه در محفظه.
شکل ۷. محدودیت‌های مرزدار در درخت UI و نمایش آن در یک محفظه.

اصلاح‌کننده size محدودیت‌های ورودی را برای مطابقت با مقدار ارسال‌شده به آن تطبیق می‌دهد. در این مثال، مقدار 150dp است:

همانند شکل ۷، با این تفاوت که اصلاح‌کننده اندازه، محدودیت‌های ورودی را با مقدار ارسال‌شده به آن مطابقت می‌دهد.
شکل ۸. تغییردهنده size محدودیت‌ها را روی 150dp تنظیم می‌کند.

اگر عرض و ارتفاع از کوچک‌ترین حد قید کوچک‌تر باشد، یا از بزرگ‌ترین حد قید بزرگ‌تر باشد، اصلاح‌کننده تا حد امکان با قیدهای ارسال‌شده مطابقت دارد و درعین‌حال همچنان از قیدهای ارسال‌شده پیروی می‌کند:

دو درخت واسط کاربر و نمایش‌های متناظر آن‌ها در محفظه‌ها. در اولی،
  اصلاح‌کننده اندازه محدودیت‌های ورودی را می‌پذیرد؛ در دومی، اصلاح‌کننده اندازه تا حد امکان با
  محدودیت‌های بسیار بزرگ سازگار می‌شود و درنتیجه محدودیت‌هایی ایجاد می‌شود که ظرف را پر می‌کند.
شکل ۹. اصلاح‌کننده size تا حد امکان به محدودیت ارسال‌شده پایبند است.

توجه داشته باشید که زنجیر کردن چند اصلاح‌کننده size کار نمی‌کند. اولین اصلاح‌کننده size هر دو محدودیت حداقل و حداکثر را روی یک مقدار ثابت تنظیم می‌کند. حتی اگر اصلاح‌کننده اندازه دوم اندازه کوچک‌تر یا بزرگ‌تری را درخواست کند، همچنان باید از حدود دقیق ارسال‌شده پیروی کند، بنابراین آن مقادیر را لغو نخواهد کرد:

زنجیره‌ای از دو اصلاح‌کننده اندازه در درخت واسط کاربر و نمایش آن در یک ظرف،
  که نتیجه اولین مقدار ارسال‌شده است و نه مقدار دوم.
شکل ۱۰. زنجیره‌ای از دو اصلاح‌کننده size که در آن مقدار دوم ارسال‌شده (50dp) مقدار اول (100dp) را لغو نمی‌کند.

اصلاح‌گر requiredSize

اگر لازم است گره شما قیدهای ورودی را لغو کند، به‌جای size از اصلاح‌کننده requiredSize استفاده کنید. اصلاح‌کننده requiredSize جایگزین محدودیت‌های ورودی می‌شود و اندازه‌ای را که مشخص می‌کنید به‌عنوان مرزهای دقیق ارسال می‌کند.

وقتی اندازه به بالای درخت برگردانده می‌شود، گره فرزند در فضای دردسترس متمرکز می‌شود:

اصلاح‌کننده size و requiredSize در درخت واسط کاربر زنجیره‌ای شده‌اند و نمایش متناظر در محفظه. محدودیت‌های اصلاح‌کننده requiredSize محدودیت‌های اصلاح‌کننده size را لغو می‌کنند.
شکل ۱۱. اصلاح‌کننده requiredSize محدودیت‌های ورودی از اصلاح‌کننده size را لغو می‌کند.

اصلاح‌کننده‌های width و height

اصلاح‌کننده size هم عرض و هم ارتفاع محدودیت‌ها را تطبیق می‌دهد. با اصلاح‌کننده width می‌توانید عرض ثابتی تنظیم کنید اما ارتفاع را نامشخص بگذارید. به‌طور مشابه، با اصلاح‌کننده height، می‌توانید ارتفاع ثابتی تنظیم کنید، اما عرض را نامشخص بگذارید:

دو درخت میانای کاربر، یکی با اصلاح‌کننده عرض و نمایشگر محفظه آن و دیگری با اصلاح‌کننده ارتفاع و نمایشگر آن.
شکل ۱۲. اصلاح‌گر width و اصلاح‌گر height به‌ترتیب عرض و ارتفاع ثابتی را تنظیم می‌کنند.

اصلاح‌گر sizeIn

اصلاح‌کننده sizeIn به شما امکان می‌دهد محدودیت‌های دقیق حداقل و حداکثر را برای عرض و ارتفاع تنظیم کنید. اگر به کنترل دقیق روی محدودیت‌ها نیاز دارید، از اصلاح‌کننده sizeIn استفاده کنید.

درخت UI با اصلاح‌کننده sizeIn با حداقل و حداکثر عرض و ارتفاع تنظیم‌شده،
  و نمایش آن در یک محفظه.
شکل ۱۳. اصلاح‌کننده sizeIn با minWidth، maxWidth، minHeight، و maxHeight تنظیم شده است.

مثال‌ها

این بخش برونداد چند تکه‌کد با اصلاح‌کننده‌های زنجیره‌ای را نشان می‌دهد و توضیح می‌دهد.

Image(
    painterResource(R.drawable.hero),
    contentDescription = null,
    Modifier
        .fillMaxSize()
        .size(50.dp)
)

این قطعه کد برونداد زیر را تولید می‌کند:

مربع آبی که ظرف اصلی خود را پر می‌کند.
شکل ۱۴. Image درنتیجه زنجیره اصلاح‌کننده، حداکثر اندازه را پر می‌کند.
  • اصلاح‌کننده fillMaxSize محدودیت‌ها را تغییر می‌دهد تا هم حداقل عرض و هم حداقل ارتفاع را روی حداکثر مقدار تنظیم کند — 300dp در عرض و 200dp در ارتفاع.
  • بااینکه اصلاح‌کننده size می‌خواهد از اندازه 50dp استفاده کند، همچنان باید از محدودیت‌های حداقل ورودی پیروی کند. بنابراین، اصلاح‌کننده size همچنین مرزهای محدودیت دقیق 300 را با 200 خروجی می‌دهد و به‌طور مؤثر مقدار ارائه‌شده در اصلاح‌کننده size را نادیده می‌گیرد.
  • ‫Image از این حدود پیروی می‌کند و اندازه 300 در 200 را گزارش می‌کند که در تمام طول درخت منتقل می‌شود.

Image(
    painterResource(R.drawable.hero),
    contentDescription = null,
    Modifier
        .fillMaxSize()
        .wrapContentSize()
        .size(50.dp)
)

این قطعه کد برونداد زیر را تولید می‌کند:

مربع آبی کوچکی که در مرکز ظرف اصلی خود قرار دارد.
شکل ۱۵. Image در مرکز قرار گرفته و اندازه آن به 50dp تغییر کرده است.
  • اصلاح‌کننده fillMaxSize محدودیت‌ها را تطبیق می‌دهد تا هم حداقل عرض و هم حداقل ارتفاع را روی حداکثر مقدار تنظیم کند — 300dp در عرض و 200dp در ارتفاع.
  • اصلاح‌گر wrapContentSize محدودیت‌های حداقل را بازنشانی می‌کند. بنابراین، درحالی‌که fillMaxSize منجر به محدودیت‌های ثابت شد، wrapContentSize آن را به محدودیت‌های مرزدار بازنشانی می‌کند. گره زیر اکنون می‌تواند دوباره کل فضا را اشغال کند، یا کوچک‌تر از کل فضا باشد.
  • اصلاح‌کننده size محدودیت‌ها را روی حداقل و حداکثر مرزهای 50 تنظیم می‌کند.
  • Image به اندازه 50 در 50 تبدیل می‌شود و اصلاح‌کننده size آن را بازارسال می‌کند.
  • اصلاح‌کننده wrapContentSize ویژگی خاصی دارد. این عنصر فرزند خود را می‌گیرد و آن را در مرکز حداقل حدود موجود که به آن منتقل شده است قرار می‌دهد. بنابراین، اندازه‌ای که به والدینش اعلام می‌کند برابر با حداقل حدودی است که به آن منتقل شده است.

با ترکیب کردن فقط سه اصلاح‌کننده، می‌توانید اندازه‌ای برای composable تعریف کنید و آن را در والدش وسط‌چین کنید.

Image(
    painterResource(R.drawable.hero),
    contentDescription = null,
    Modifier
        .clip(CircleShape)
        .padding(10.dp)
        .size(100.dp)
)

این قطعه کد برونداد زیر را تولید می‌کند:

شکل دایره‌ای که به‌دلیل ترتیب اصلاح‌کننده‌ها به‌اشتباه بریده شده است.
شکل ۱۶. شکلی که به‌دلیل ترتیب اصلاح‌کننده‌ها به‌اشتباه برش داده شده است.
  • اصلاح‌کننده clip محدودیت‌ها را تغییر نمی‌دهد.
  • اصلاح‌کننده padding حداکثر محدودیت‌ها را کاهش می‌دهد.
  • توصیف‌گر size همه محدودیت‌ها را روی 100dp تنظیم می‌کند.
  • ‫Image از این محدودیت‌ها پیروی می‌کند و اندازه 100dp در 100dp را گزارش می‌کند.
  • اصلاح‌کننده padding مقدار 10dp را به همه طرف‌های اندازه گزارش‌شده توسط Image اضافه می‌کند، بنابراین طرح‌بندی با لایه داخلی عرض و ارتفاع 120dp را گزارش می‌کند.
  • اکنون، در مرحله طراحی، اصلاح‌کننده clip روی بوم 120dp در 120dp عمل می‌کند. این کار ماسک دایره‌ای با آن اندازه ایجاد می‌کند.
  • سپس اصلاح‌کننده padding محتوای خود را با 10dp در همه طرف‌ها درج می‌کند، که اندازه بوم را برای Image به 100dp با 100dp کاهش می‌دهد.
  • Image در آن بوم کوچک‌تر ترسیم می‌شود. تصویر براساس دایره اصلی 120dp برش داده شده است، بنابراین خروجی نتیجه‌ای غیرگرد است.