কনস্ট্রেন্ট ও মডিফায়ার অর্ডার

Compose-এ, আপনি কম্পোজেবলের লুক ও ফিল পরিবর্তন করতে একাধিক মডিফায়ার একসাথে চেইন করতে পারেন। এই মডিফায়ার চেন কম্পোজেবলে পাস করা কনস্ট্রেনকে প্রভাবিত করতে পারে, যা প্রস্থ এবং উচ্চতার সীমা নির্ধারণ করে।

এই পৃষ্ঠায় বর্ণনা করা হয়েছে যে কীভাবে চেইনড মডিফায়ার কনস্ট্রেন্টকে প্রভাবিত করে এবং এর ফলে কম্পোজেবলের পরিমাপ ও প্লেসমেন্টকে প্রভাবিত করে।

UI ট্রিতে মডিফায়ার

মডিফায়ারগুলি কীভাবে একে অপরকে প্রভাবিত করে তা বোঝার জন্য, কম্পোজিশন ফেজ চলাকালীন জেনারেট হওয়া UI ট্রিতে সেগুলি কীভাবে দেখা যায় তা ভিজ্যুয়ালাইজ করা সহায়ক। আরও তথ্যের জন্য, কম্পোজিশন বিভাগ দেখুন।

UI ট্রিতে, আপনি লেআউট নোডের জন্য মডিফায়ারকে র‍্যাপার নোড হিসেবে দেখতে পাবেন:

কম্পোজেবল ও মডিফায়ারের কোড এবং UI ট্রি হিসেবে সেগুলির ভিজ্যুয়াল উপস্থাপনা।
ছবি ১. UI ট্রি-তে লেআউট নোড র‍্যাপ করা মডিফায়ার।

কম্পোজেবলে একাধিক মডিফায়ার যোগ করলে মডিফায়ারের একটি চেইন তৈরি হয়। আপনি একাধিক মডিফায়ার চেইন করলে, প্রতিটি মডিফায়ার নোড চেইনের বাকি অংশ এবং লেআউট নোডকে র‍্যাপ করে। যেমন, আপনি যখন একটি clip এবং একটি size মডিফায়ার চেইন করেন, তখন clip মডিফায়ার নোড size মডিফায়ার নোডকে র‍্যাপ করে, যা পরে Image লেআউট নোডকে র‍্যাপ করে।

লেআউট ফেজে, অ্যালগরিদম যা ট্রি ওয়াক করে একই থাকে, তবে প্রতিটি মডিফায়ার নোডও ভিজিট করা হয়। এইভাবে, একটি মডিফায়ার সাইজ পরিবর্তন করতে পারে মডিফায়ার বা লেআউট নোডের প্রয়োজনীয়তা এবং প্লেসমেন্ট যা এটি মোড়ানো হয়।

২ নম্বর ছবিতে যেমন দেখানো হয়েছে, Image ও Text কম্পোজেবলের প্রয়োগের মধ্যে একটি লেআউট নোডকে র‍্যাপ করা মডিফায়ারের একটি চেইন থাকে।

Row এবং Column-এর প্রয়োগ হল লেআউট নোড যা বর্ণনা করে যে কীভাবে তাদের চাইল্ড লেআউট করতে হবে।

আগের মতো ট্রি স্ট্রাকচার, তবে এখন প্রতিটি নোড হল একটি সাধারণ লেআউট, যার চারপাশে প্রচুর মডিফায়ার র‍্যাপিং নোড রয়েছে।
ছবি ২. ছবি ১-এর মতো একই ট্রি স্ট্রাকচার, তবে UI ট্রিতে কম্পোজেবলগুলি মডিফায়ারের চেইন হিসাবে দেখানো হয়েছে।

সংক্ষেপে:

  • মডিফায়ার একটি একক মডিফায়ার বা লেআউট নোডকে র‍্যাপ করে।
  • লেআউট নোড একাধিক চাইল্ড নোড লেআউট করতে পারে।

নিম্নলিখিত বিভাগগুলি বর্ণনা করে যে কীভাবে এই মানসিক মডেলটি মডিফায়ার চেইনিং সম্পর্কে যুক্তি দিতে ব্যবহার করা যায় এবং কীভাবে এটি কম্পোজেবলের আকারকে প্রভাবিত করে।

লেআউট ফেজে সীমাবদ্ধতা

লেআউট ফেজ প্রতিটি লেআউট নোডের প্রস্থ, উচ্চতা এবং x, y স্থানাঙ্ক খুঁজে পেতে তিন-ধাপের অ্যালগরিদম অনুসরণ করে:

  1. চিলড্রেন পরিমাপ করা: কোনও নোড তার চিলড্রেনকে পরিমাপ করে, যদি থাকে।
  2. নিজেই সাইজ নির্ধারণ করা: সেই পরিমাপের উপর ভিত্তি করে, একটি নোড নিজেই নিজের সাইজ নির্ধারণ করে।
  3. চাইল্ড নোড প্লেস করা: প্রতিটি চাইল্ড নোডকে নোডের নিজস্ব অবস্থানের সাপেক্ষে প্লেস করা হয়।

Constraints অ্যালগরিদমের প্রথম দুটি ধাপে নোডের সঠিক সাইজ খুঁজে পেতে সাহায্য করে। কনস্ট্রেইন্ট কোনও নোডের প্রস্থ ও উচ্চতার সর্বনিম্ন ও সর্বোচ্চ সীমা নির্ধারণ করে। নোড যখন তার সাইজ নির্ধারণ করে, তখন তার পরিমাপ করা সাইজ এই সাইজ রেঞ্জের মধ্যে হওয়া উচিত।

বাধার ধরন

নিম্নলিখিতগুলির মধ্যে যেকোনও একটি কনস্ট্রেন্ট হতে পারে:

  • বাউন্ডেড: নোডের সর্বাধিক ও সর্বনিম্ন প্রস্থ ও উচ্চতা আছে।
একটি কন্টেনারের মধ্যে বিভিন্ন সাইজের বাউন্ডেড কনস্ট্রেন্ট।
ছবি ৩. সীমাবদ্ধ বাধ্যবাধকতা।
  • আনবাউন্ডেড: নোডটি কোনও সাইজে সীমাবদ্ধ নয়। সর্বাধিক প্রস্থ এবং উচ্চতার সীমা অসীম সেট করা হয়েছে।
সীমাহীন সীমাবদ্ধতা যার প্রস্থ এবং উচ্চতা অসীম সেট করা আছে। কনস্ট্রেন্ট কন্টেনারের বাইরে চলে গেছে।
ছবি ৪. সীমাহীন সীমাবদ্ধতা।
  • নির্দিষ্ট: নোডকে নির্দিষ্ট সাইজের প্রয়োজনীয়তা মেনে চলতে বলা হয়। সর্বনিম্ন এবং সর্বোচ্চ সীমা একই ভ্যালুতে সেট করা হয়েছে।
কন্টেনারের মধ্যে নির্দিষ্ট সাইজের প্রয়োজনীয়তার সাথে মানানসই নির্দিষ্ট সীমাবদ্ধতা।
ছবি ৫. যথাযথ সীমাবদ্ধতা।
  • কম্বিনেশন: নোডটি পূর্ববর্তী কনস্ট্রেন্ট ধরনের কম্বিনেশন অনুসরণ করে। যেমন, কোনও কনস্ট্রেন্ট প্রস্থকে সীমাবদ্ধ করতে পারে, যেখানে সর্বোচ্চ উচ্চতা সীমাবদ্ধ নাও হতে পারে, অথবা সঠিক প্রস্থ সেট করতে পারে, যেখানে উচ্চতা সীমাবদ্ধ হতে পারে।
দুটি কন্টেনার যা বাউন্ডেড এবং আনবাউন্ডেড কনস্ট্রেন্টের কম্বিনেশন এবং সঠিক প্রস্থ এবং উচ্চতা দেখায়।
ছবি ৬. বাউন্ডেড ও আনবাউন্ডেড কনস্ট্রেন্টের কম্বিনেশন এবং সঠিক প্রস্থ ও উচ্চতা।

পরবর্তী বিভাগে বর্ণনা করা হয়েছে যে কীভাবে এই সীমাবদ্ধতাগুলি পেরেন্ট থেকে চাইল্ডে পাস করা হয়।

অভিভাবক থেকে সন্তানের কাছে কীভাবে সীমাবদ্ধতা পাস করা হয়

লেআউট ফেজে কনস্ট্রেন্ট-এ বর্ণিত অ্যালগরিদমের প্রথম ধাপে, UI ট্রিতে কনস্ট্রেন্ট পেরেন্ট থেকে চাইল্ডে পাস করা হয়।

যখন একটি পেরেন্ট নোড তার চাইল্ড নোডগুলিকে পরিমাপ করে, তখন এটি প্রতিটি চাইল্ড নোডকে এই সীমাবদ্ধতাগুলি প্রদান করে যাতে তারা জানতে পারে যে তারা কতটা বড় বা ছোট হতে পারে। তারপর, যখন এটি নিজের সাইজ নির্ধারণ করে, তখন এটি তার নিজের পেরেন্ট দ্বারা পাস করা সীমাবদ্ধতাগুলিও মেনে চলে।

এক নজরে, অ্যালগরিদমটি নিম্নলিখিত উপায়ে কাজ করে:

  1. UI ট্রিতে রুট নোড কতটা জায়গা নেবে তা নির্ধারণ করতে, এটি চাইল্ড নোড পরিমাপ করে এবং প্রথম চাইল্ড নোডে একই সীমাবদ্ধতা প্রয়োগ করে।
  2. চাইল্ড যদি এমন মডিফায়ার হয় যা পরিমাপকে প্রভাবিত করে না, তাহলে এটি পরবর্তী মডিফায়ারে কনস্ট্রেন্ট ফরওয়ার্ড করে। পরিমাপকে প্রভাবিত করে এমন মডিফায়ারে না পৌঁছানো পর্যন্ত কনস্ট্রেনগুলি মডিফায়ার চেনে যেমন আছে তেমনভাবে পাস করা হয়। সেই অনুযায়ী কনস্ট্রেনগুলি আবার সাইজ করা হয়।
  3. কোনও চাইল্ড নেই এমন নোডে (যাকে "লিফ নোড" বলা হয়) পৌঁছালে, এটি পাস করা সীমাবদ্ধতার উপর ভিত্তি করে এর সাইজ নির্ধারণ করে এবং এই সমাধান করা সাইজটি এর পেরেন্টকে ফেরত দেয়।
  4. পেরেন্ট এই চাইল্ডের পরিমাপের উপর ভিত্তি করে তার সীমাবদ্ধতাগুলি মানিয়ে নেয় এবং এই অ্যাডজাস্ট করা সীমাবদ্ধতার সাথে তার পরবর্তী চাইল্ডকে কল করে।
  5. কোনও পেরেন্ট নোডের সব চাইল্ড নোড পরিমাপ করা হয়ে গেলে, পেরেন্ট নোড নিজের সাইজ নির্ধারণ করে এবং তার পেরেন্ট নোডকে তা জানায়।
  6. এইভাবে, পুরো ট্রি ডেপথ-ফার্স্ট পদ্ধতিতে ট্রাভার্স করা হয়। অবশেষে, সব নোড তাদের সাইজ নির্ধারণ করে এবং পরিমাপের ধাপটি সম্পূর্ণ হয়।

বিস্তারিত উদাহরণের জন্য, কনস্ট্রেন্ট ও মডিফায়ার অর্ডার ভিডিওটি দেখুন।

মডিফায়ার যা সীমাবদ্ধতাকে প্রভাবিত করে

আপনি আগের বিভাগে জেনেছেন যে কিছু মডিফায়ার কনস্ট্রেন্ট সাইজকে প্রভাবিত করতে পারে। নিম্নলিখিত বিভাগে নির্দিষ্ট মডিফায়ার সম্পর্কে বর্ণনা করা হয়েছে যা সীমাবদ্ধতাকে প্রভাবিত করে।

size মডিফায়ার

size মডিফায়ার কন্টেন্টের পছন্দের সাইজ ঘোষণা করে।

যেমন, নিম্নলিখিত UI ট্রি 300dp বাই 200dp-এর কন্টেনারে রেন্ডার করা উচিত। সীমাবদ্ধতাগুলি বাউন্ডেড, যা 100dp এবং 300dp-এর মধ্যে প্রস্থ এবং 100dp এবং 200dp-এর মধ্যে উচ্চতার অনুমতি দেয়:

UI ট্রির একটি অংশ যেখানে সাইজ মডিফায়ার একটি লেআউট নোডকে র‍্যাপ করে এবং
  কন্টেনারে সাইজ মডিফায়ার দ্বারা সেট করা বাউন্ডেড কনস্ট্রেন্টের উপস্থাপনা।
ছবি ৭. UI ট্রি-তে বাউন্ডেড কনস্ট্রেন্ট এবং কন্টেনারে এর উপস্থাপনা।

size মডিফায়ার ইনকামিং কনস্ট্রেন্টকে অ্যাডাপ্ট করে যাতে এটিতে পাস করা ভ্যালুর সাথে ম্যাচ করে। এই উদাহরণে, ভ্যালু হল 150dp:

ছবি ৭-এর মতোই, তবে সাইজ মডিফায়ার ইনকামিং কনস্ট্রেন্টকে অ্যাডাপ্ট করে যাতে এটিতে পাস করা ভ্যালুর সাথে ম্যাচ করে।
ছবি ৮. size মডিফায়ার 150dp-এ কনস্ট্রেন্ট অ্যাডজাস্ট করছে।

প্রস্থ এবং উচ্চতা যদি ক্ষুদ্রতম সীমাবদ্ধতার সীমার চেয়ে ছোট হয়, বা বৃহত্তম সীমাবদ্ধতার সীমার চেয়ে বড় হয়, তাহলে মডিফায়ারটি পাস করা সীমাবদ্ধতার সাথে যতটা সম্ভব ঘনিষ্ঠভাবে মেলে এবং এখনও পাস করা সীমাবদ্ধতাগুলি মেনে চলে:

দুটি UI ট্রি এবং কন্টেনারে তাদের সংশ্লিষ্ট উপস্থাপনা। প্রথমটিতে, সাইজ মডিফায়ার ইনকামিং সীমাবদ্ধতা গ্রহণ করে; দ্বিতীয়টিতে, সাইজ মডিফায়ার
  খুব বড় সীমাবদ্ধতার সাথে যতটা সম্ভব মানিয়ে নেয়, যার ফলে সীমাবদ্ধতা কন্টেনার পূরণ করে।
ছবি ৯. size মডিফায়ার যতটা সম্ভব পাস করা কনস্ট্রেন্টের সাথে মানানসই।

মনে রাখবেন, একাধিক size মডিফায়ার চেইন করা কাজ করে না। প্রথম size মডিফায়ার ন্যূনতম ও সর্বাধিক সীমাবদ্ধতা একটি নির্দিষ্ট ভ্যালুতে সেট করে। এমনকি যদি দ্বিতীয় সাইজ মডিফায়ার ছোট বা বড় সাইজের অনুরোধ করে, তবুও এটিতে পাস করা সঠিক বাউন্ড মেনে চলতে হবে, তাই এটি সেইসব ভ্যালু ওভাররাইড করবে না:

UI ট্রি-তে দুটি সাইজ মডিফায়ারের একটি চেইন এবং একটি কন্টেনারে এর উপস্থাপনা,
  যা পাস করা প্রথম ভ্যালুর ফলাফল এবং দ্বিতীয় ভ্যালুর নয়।
ছবি ১০. দুটি size মডিফায়ারের একটি চেইন, যেখানে দ্বিতীয় ভ্যালু (50dp) প্রথম ভ্যালুকে (100dp) ওভাররাইড করে না।

requiredSize মডিফায়ার

আপনার নোডকে ইনকামিং কনস্ট্রেন্ট ওভাররাইড করতে হলে, size-এর পরিবর্তে requiredSize মডিফায়ার ব্যবহার করুন। requiredSize মডিফায়ার ইনকামিং কনস্ট্রেন্ট পরিবর্তন করে এবং আপনার উল্লেখ করা সাইজ সঠিক বাউন্ড হিসেবে পাস করে।

সাইজটি ট্রি-তে পাস ব্যাক করা হলে, চাইল্ড নোডটি উপলভ্য স্পেসে সেন্টার করা হবে:

UI ট্রিতে size ও requiredSize মডিফায়ার চেইন করা আছে এবং কন্টেনারে সংশ্লিষ্ট
  রিপ্রেজেন্টেশন। requiredSize মডিফায়ার কনস্ট্রেন্ট, সাইজ মডিফায়ার কনস্ট্রেন্টকে
  ওভাররাইড করে।
ছবি ১১. requiredSize মডিফায়ার size মডিফায়ার থেকে আসা সীমাবদ্ধতা ওভাররাইড করছে।

width এবং height মডিফায়ার

size মডিফায়ার কনস্ট্রেন্টের প্রস্থ ও উচ্চতা, দুটিই অ্যাডাপ্ট করে। width মডিফায়ার ব্যবহার করে আপনি নির্দিষ্ট প্রস্থ সেট করতে পারবেন, তবে উচ্চতা সেট করতে হবে না। একইভাবে, height মডিফায়ার ব্যবহার করে আপনি নির্দিষ্ট উচ্চতা সেট করতে পারবেন, কিন্তু প্রস্থ অনির্ধারিত রাখতে পারবেন:

দুটি UI ট্রি, একটি প্রস্থ মডিফায়ার ও তার কন্টেনার উপস্থাপনা সহ এবং অন্যটি
  উচ্চতা মডিফায়ার ও তার উপস্থাপনা সহ।
ছবি ১২. width মডিফায়ার এবং height মডিফায়ার যথাক্রমে নির্দিষ্ট প্রস্থ এবং উচ্চতা সেট করছে।

sizeIn মডিফায়ার

sizeIn মডিফায়ার আপনাকে প্রস্থ ও উচ্চতার জন্য সঠিক ন্যূনতম ও সর্বাধিক সীমাবদ্ধতা সেট করতে দেয়। কনস্ট্রেন্টের উপর আরও সূক্ষ্ম কন্ট্রোল প্রয়োজন হলে, sizeIn মডিফায়ার ব্যবহার করুন।

সর্বনিম্ন ও সর্বাধিক প্রস্থ ও উচ্চতা সেট করা sizeIn মডিফায়ার সহ UI ট্রি
  এবং কন্টেনারের মধ্যে এটির উপস্থাপনা।
ছবি ১৩. 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 x 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-এর দ্বারা রিপোর্ট করা সাইজে, তাই প্যাডিং সহ লেআউট 120dp-এর প্রস্থ ও উচ্চতা রিপোর্ট করে।
  • এখন, ড্রয়িং ফেজে, clip মডিফায়ার 120dp বাই 120dp ক্যানভাসে কাজ করে। এটি সেই সাইজের একটি বৃত্তাকার মাস্ক তৈরি করে।
  • padding মডিফায়ার তারপর সব দিকে 10dp দ্বারা এর কন্টেন্ট ইনসেট করে, যা Image-এর জন্য ক্যানভাস সাইজ কমিয়ে 100dp-এর জন্য 100dp করে।
  • Image সেই ছোট ক্যানভাসে আঁকা হয়। 120dp-এর আসল বৃত্তের উপর ভিত্তি করে ছবিটি ক্লিপ করা হয়েছে, তাই আউটপুটটি একটি অ-বৃত্তাকার ফলাফল।