محدودیت ها و ترتیب اصلاح کننده ها

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

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

اصلاح‌کننده‌ها در درخت رابط کاربری

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

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

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

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

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

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

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

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

خلاصه کنم:

  • اصلاح‌کننده‌ها یک اصلاح‌کننده یا گره طرح‌بندی واحد را در بر می‌گیرند.
  • گره‌های طرح‌بندی می‌توانند چندین گره فرزند را طرح‌بندی کنند.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

اصلاح کننده size

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

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

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

اصلاح‌کننده‌ی 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 استفاده کنید.

یک درخت رابط کاربری با اصلاح‌کننده 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 یک ویژگی خاص دارد. این اصلاح‌کننده، فرزند خود را می‌گیرد و آن را در مرکز حداقل مرزهای موجود که به آن منتقل شده است، قرار می‌دهد . بنابراین، اندازه‌ای که به والدهای خود اطلاع می‌دهد، برابر با حداقل مرزهایی است که به آن منتقل شده است.

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

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 اضافه می‌کند، بنابراین طرح‌بندی با padding، عرض و ارتفاع 120dp را گزارش می‌دهد.
  • اکنون، در مرحله طراحی، اصلاح‌کننده clip روی یک بوم با 120dp در 120dp عمل می‌کند و یک ماسک دایره‌ای با این اندازه ایجاد می‌کند.
  • سپس اصلاح‌کننده‌ی padding محتوای خود را از هر طرف به اندازه‌ی 10dp وارد می‌کند که اندازه‌ی بوم Image را به 100dp در 100dp کاهش می‌دهد.
  • Image در آن بوم کوچک‌تر رسم می‌شود. تصویر بر اساس دایره اصلی 120dp برش داده می‌شود، بنابراین خروجی یک نتیجه غیر گرد است.