আমরা RelativeLayout-এর সারমর্ম ব্যাখ্যা করি — Android SDK-তে একটি ViewGroup যা চাইল্ড এলিমেন্টগুলিকে একে অপরের সাপেক্ষে বা প্যারেন্ট কন্টেইনারের সাপেক্ষে অবস্থান নির্ধারণ করে। LinearLayout-এর বিপরীতে, যা এলিমেন্টগুলিকে কঠোরভাবে ক্রমানুসারে সাজায়, RelativeLayout আপনাকে যেকোনো এলিমেন্টকে অন্য যেকোনো এলিমেন্টের বামে, ডানে, উপরে, নীচে বা মাঝখানে তার ID দ্বারা রাখতে দেয়। এটি RelativeLayout-কে নেস্টিং ছাড়াই ওভারল্যাপিং এবং জটিল লেআউটের জন্য সুবিধাজনক করে তোলে। মৌলিক নিয়মগুলি Android Developers ডকুমেন্টেশন-এ বর্ণিত হয়েছে।
মূল পয়েন্ট
RelativeLayout — একটি ViewGroup যা Android SDK-তে API Level 1 থেকে চালু হয়েছে, যা ঘোষণামূলক নিয়মের (layout rules) মাধ্যমে চাইল্ড এলিমেন্টগুলিকে প্যারেন্ট বা অন্যান্য চাইল্ড এলিমেন্টের সাপেক্ষে অবস্থান নির্ধারণ করে। প্রতিটি নিয়ম একটি XML অ্যাট্রিবিউট দ্বারা সেট করা হয় যেমন android:layout_above, android:layout_below, android:layout_toLeftOf যাতে লক্ষ্য এলিমেন্টের ID-র মান থাকে।
RelativeLayout আসার আগে, ডেভেলপারদের প্রতিটি অ-মানক অবস্থানের জন্য নেস্টেড LinearLayout ব্যবহার করতে হত — এতে গভীর নেস্টিং এবং ধীর রেন্ডারিং হত। RelativeLayout একটি একক স্তরের শ্রেণিবিন্যাসে আপেক্ষিক অবস্থান নির্ধারণের অফার করে এই সমস্যার সমাধান করেছে। তবে, এর নমনীয়তা আধুনিক ConstraintLayout-এর তুলনায় সীমিত: RelativeLayout চেইন, ব্যারিয়ার, গাইডলাইন বা শতাংশ-ভিত্তিক মাত্রা সমর্থন করে না।
RelativeLayout-এর দুটি মূল বৈশিষ্ট্য রয়েছে: একটি onMeasure পাস (LinearLayout-এর বিপরীতে যার weight-এর জন্য দুটি পাস প্রয়োজন) এবং ঘোষণা ক্রমের উপর নির্ভরশীলতা — যদি এলিমেন্ট A এলিমেন্ট B-কে নির্দেশ করে, এবং B, A-এর পরে ঘোষিত হয়, তাহলে A-র মাপার সময় B-র আকার জানা থাকতে হবে। Android Developers Guide (2024) অনুসারে, RelativeLayout একটি পাসে মাপন সম্পাদন করে যদি সমস্ত নিয়ম ইতিমধ্যে মাপা এলিমেন্টগুলিকে নির্দেশ করে। অন্যথায়, দ্বিতীয় পাসের প্রয়োজন হয়, যা কর্মক্ষমতা হ্রাস করে।
RelativeLayout সহজ লেআউটের জন্য ন্যায়সঙ্গত যাতে 3–7টি এলিমেন্ট থাকে যেখানে আপেক্ষিক অবস্থান প্রয়োজন (বাটনের উপরে লেবেল, টেক্সটের ডানে আইকন, স্ক্রিনের নীচে প্যানেল)। নতুন প্রকল্পের জন্য, ConstraintLayout সুপারিশ করা হয়, কিন্তু RelativeLayout এখনও লিগ্যাসি কোড এবং লাইব্রেরিতে ব্যাপকভাবে ব্যবহৃত হয়।
RelativeLayout দুই ধরনের নিয়ম ব্যবহার করে: relative নিয়ম (অন্য এলিমেন্টের সাপেক্ষে অবস্থান নির্ধারণ) এবং align নিয়ম (প্যারেন্টে অ্যাঙ্কর করা)। প্রতিটি চাইল্ড এলিমেন্টের সীমাহীন সংখ্যক নিয়ম থাকতে পারে, কিন্তু বিরোধী নিয়ম (যেমন, alignParentTop এবং অন্য এলিমেন্টের below) শেষ ঘোষিত অ্যাট্রিবিউটের পক্ষে সমাধান করা হয়।
Relative নিয়ম:
- android:layout_above="@id/target" — এলিমেন্টের নীচের প্রান্ত target-এর উপরের প্রান্তে অ্যাঙ্কর হয়।
- android:layout_below="@id/target" — এলিমেন্টের উপরের প্রান্ত target-এর নীচের প্রান্তে অ্যাঙ্কর হয়।
- android:layout_toLeftOf="@id/target" — ডান প্রান্ত target-এর বাম প্রান্তে অ্যাঙ্কর হয়।
- android:layout_toRightOf="@id/target" — বাম প্রান্ত target-এর ডান প্রান্তে অ্যাঙ্কর হয়।
- android:layout_toStartOf="@id/target" — RTL লোকেলের জন্য toLeftOf-এর অনুরূপ।
- android:layout_toEndOf="@id/target" — RTL-এর জন্য toRightOf-এর অনুরূপ।
Align নিয়ম (প্যারেন্টে):
- android:layout_alignParentTop="true" — এলিমেন্টের উপরের প্রান্ত প্যারেন্টের উপরের প্রান্তের সাথে মিলে যায়।
- android:layout_alignParentBottom="true" — নীচের প্রান্ত প্যারেন্টের নীচের প্রান্তের সাথে মিলে যায়।
- android:layout_alignParentLeft="true" — বাম প্রান্ত প্যারেন্টের বাম প্রান্তের সাথে মিলে যায়।
- android:layout_alignParentRight="true" — ডান প্রান্ত প্যারেন্টের ডান প্রান্তের সাথে মিলে যায়।
- android:layout_alignParentStart এবং android:layout_alignParentEnd — RTL-এর জন্য।
অন্যান্য এলিমেন্টে align নিয়ম:
- android:layout_alignTop="@id/target" — এলিমেন্টের উপরের অংশ target-এর উপরের অংশের সাথে মিলে যায়।
- android:layout_alignBottom, android:layout_alignLeft, android:layout_alignRight, android:layout_alignStart, android:layout_alignEnd — অনুরূপ।
- android:layout_alignBaseline="@id/target" — টেক্সট বেসলাইন দ্বারা সারিবদ্ধকরণ (বিভিন্ন ফন্ট সাইজের স্ট্রিংয়ের জন্য দরকারী)।
RelativeLayout-এ কেন্দ্রীভূতকরণ তিনটি অ্যাট্রিবিউট দ্বারা সেট করা হয়: android:layout_centerInParent="true" (উভয় অক্ষে প্যারেন্টের কেন্দ্র), android:layout_centerHorizontal="true" (অনুভূমিকভাবে কেন্দ্র) এবং android:layout_centerVertical="true" (উল্লম্বভাবে কেন্দ্র)। কেন্দ্রীভূতকরণ অন্যান্য নিয়মের সাথে সামঞ্জস্যপূর্ণ: একটি এলিমেন্ট অনুভূমিকভাবে কেন্দ্রীভূত হতে পারে এবং প্যারেন্টের নীচের প্রান্তে অ্যাঙ্কর থাকতে পারে।
Z-ক্রম (ওভারলে ক্রম) RelativeLayout-এ XML-এ এলিমেন্ট ঘোষণার ক্রম দ্বারা নির্ধারিত হয়। প্রথম ঘোষিত এলিমেন্ট প্রথমে আঁকা হয় (নীচে থাকবে), শেষ — শেষে (উপরে থাকবে)। যদি আপনি XML না বদলে ওভারলে ক্রম পরিবর্তন করতে চান, তাহলে android:elevation (API 21 থেকে) ব্যবহার করুন — বেশি elevation-যুক্ত এলিমেন্ট উপরে আঁকা হয়। API 21-এর নীচের সংস্করণের জন্য, ওভারলে ক্রম শুধুমাত্র ঘোষণা ক্রম দ্বারা নিয়ন্ত্রিত হয়।
গুরুত্বপূর্ণ: RelativeLayout প্যারেন্টের জন্য android:elevation অ্যাট্রিবিউট সমর্থন করে না — প্রতিটি এলিমেন্ট নিজস্ব elevation নিয়ন্ত্রণ করে। যখন অবস্থান নির্ধারণের নিয়ম এবং elevation বিরোধ করে (যেমন, ওভারল্যাপিং এলিমেন্ট), রেন্ডারিংয়ের জন্য elevation অগ্রাধিকার পায়, কিন্তু অবস্থান নির্ধারণের জন্য নয় — বেশি elevation-যুক্ত এলিমেন্ট অন্যটিকে দৃশ্যত ওভারল্যাপ করতে পারে, এমনকি যদি তার লেআউট নিয়ম এটিকে "পিছনে" রাখে।
অবতার উপরে কেন্দ্রীভূত, নাম অবতারের নীচে, অবস্থা নামের নীচে, অ্যাকশন বাটন স্ক্রিনের নীচে। সমস্ত এলিমেন্ট ক্রমিক অ্যাঙ্করিংয়ের জন্য relative নিয়ম ব্যবহার করে।
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/avatar"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="32dp"
android:src="@drawable/avatar_placeholder" />
<TextView
android:id="@+id/user_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/avatar"
android:layout_centerHorizontal="true"
android:layout_marginTop="12dp"
android:text="ইভান ইভানভ"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:id="@+id/user_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/user_name"
android:layout_centerHorizontal="true"
android:text="অনলাইন"
android:textColor="@color/green" />
<Button
android:id="@+id/edit_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="24dp"
android:text="প্রোফাইল সম্পাদনা করুন" />
</RelativeLayout>
অবতার marginTop + centerHorizontal-এর মাধ্যমে উপরে অ্যাঙ্কর, নাম layout_below-এর মাধ্যমে অবতারের নীচে, অবস্থা নামের নীচে, এবং বাটন alignParentBottom-এর মাধ্যমে প্যারেন্টের নীচের প্রান্তে অ্যাঙ্কর। সমস্ত এলিমেন্ট একে অপরের থেকে স্বাধীন — কোনো চেইন বা নেস্টিং নেই।
একটি আইকন যার উপরের ডান কোণে লাল ব্যাজ (সংখ্যা সহ বৃত্ত) রয়েছে। ব্যাজটি আইকনের সাপেক্ষে তার প্রান্তে সারিবদ্ধকরণের মাধ্যমে ওভারল্যাপের জন্য নেতিবাচক মার্জিন সহ অবস্থিত।
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/icon"
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@drawable/ic_notification" />
<TextView
android:id="@+id/badge"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignTop="@+id/icon"
android:layout_alignRight="@+id/icon"
android:layout_marginTop="-6dp"
android:layout_marginRight="-6dp"
android:gravity="center"
android:background="@drawable/badge_background"
android:text="3"
android:textColor="@android:color/white"
android:textSize="10sp" />
</RelativeLayout>
ব্যাজটি আইকনের উপরের এবং ডান প্রান্তে অ্যাঙ্কর। নেতিবাচক মার্জিন (-6dp) ব্যাজটিকে বাইরের দিকে সরিয়ে দেয়, আইকনের সীমানা ওভারল্যাপ করার প্রভাব তৈরি করে। এটি নোটিফিকেশনের জন্য একটি জনপ্রিয় প্যাটার্ন, যার জন্য RelativeLayout ছাড়া FrameLayout বা কাস্টম ড্রইং প্রয়োজন হত।
লগইন ফর্ম: লোগো উপরে কেন্দ্রীভূত, তার নীচে ইমেল ফিল্ড, ইমেলের নীচে পাসওয়ার্ড ফিল্ড, পাসওয়ার্ডের নীচে "লগইন" বাটন, "নিবন্ধন" লিংক নীচে থেকে অ্যাঙ্কর। সমস্ত এলিমেন্ট layout_below-এর মাধ্যমে ক্রমিকভাবে অ্যাঙ্কর।
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="24dp">
<TextView
android:id="@+id/logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="48dp"
android:text="MyApp"
android:textSize="32sp"
android:textStyle="bold" />
<EditText
android:id="@+id/email_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/logo"
android:layout_marginTop="32dp"
android:hint="Email" />
<EditText
android:id="@+id/password_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/email_input"
android:layout_marginTop="16dp"
android:hint="পাসওয়ার্ড"
android:inputType="textPassword" />
<Button
android:id="@+id/login_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/password_input"
android:layout_marginTop="24dp"
android:text="লগইন করুন" />
<TextView
android:id="@+id/register_link"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="16dp"
android:text="অ্যাকাউন্ট নেই? নিবন্ধন করুন"
android:textColor="@color/primary" />
</RelativeLayout>
স্ক্রিনটি একটি একক স্তরের শ্রেণিবিন্যাসে 5টি এলিমেন্ট ব্যবহার করে। উপরে-থেকে-নীচে প্রবাহ (লোগো → ইমেল → পাসওয়ার্ড → বাটন) layout_below-এর মাধ্যমে অর্জিত হয়, এবং লিংকটি alignParentBottom-এর মাধ্যমে নীচে ঠেলে দেওয়া হয়। একই কার্যকারিতার জন্য, LinearLayout-এ দুটি নেস্টেড কন্টেইনার প্রয়োজন হত (একটি উপরের গ্রুপের জন্য, অন্যটি weight সহ লিংকের জন্য)।
আপেক্ষিক অবস্থান নির্ধারণের জন্য দুটি ViewGroup-এর তুলনা: RelativeLayout (ক্লাসিক, API 1+) এবং ConstraintLayout (আধুনিক, Jetpack)। মানদণ্ড: নমনীয়তা, কর্মক্ষমতা, RTL সমর্থন এবং অভিযোজনযোগ্যতা।
| বৈশিষ্ট্য | RelativeLayout | ConstraintLayout |
|---|---|---|
| শতাংশ মাত্রা | না (শুধু ফিক্সড এবং match_parent) | হ্যাঁ (width_percent, height_percent, guideline_percent) |
| RTL সমর্থন | start/end-এর মাধ্যমে (API 17+) | অন্তর্নির্মিত |
| Chain / শৃঙ্খল | না | হ্যাঁ (spread, spread_inside, packed) |
| Barrier / Group / Flow | না | হ্যাঁ (ভার্চুয়াল হেল্পার) |
| MotionLayout অ্যানিমেশন | না | হ্যাঁ |
| onMeasure পাস | 1 (নির্ভরতা চক্র ছাড়া) | 2 (সর্বদা, কিন্তু অপ্টিমাইজড) |
| কেন্দ্রীভূতকরণ | centerInParent, centerHorizontal, centerVertical | বিপরীত কনস্ট্রেইন্ট সহ bias (0.0–1.0)-এর মাধ্যমে |
| কখন ব্যবহার করবেন | লিগ্যাসি কোড, 3–7 এলিমেন্ট সহ সহজ লেআউট | নতুন প্রকল্প, জটিল স্ক্রিন, অভিযোজী লেআউট |
RelativeLayout প্রায় প্রতিটি দিকেই ConstraintLayout-এর থেকে নিকৃষ্ট একটি ব্যতীত: এটি API 1 থেকে Android SDK-তে নির্মিত এবং অতিরিক্ত নির্ভরতার প্রয়োজন হয় না। যে প্রকল্পগুলি এখনও API 14 (Android 4.0)-এর নীচে minSdk ব্যবহার করে, তাদের জন্য RelativeLayout আপেক্ষিক অবস্থান নির্ধারণের একমাত্র মানক বিকল্প। অন্যান্য সমস্ত ক্ষেত্রে, Google ConstraintLayout সুপারিশ করে।
প্রায়শই জিজ্ঞাসিত প্রশ্ন
সবচেয়ে সম্ভাব্য কারণ পর্যাপ্ত অবস্থান নির্ধারণের নিয়মের অভাব। RelativeLayout-এ প্রতিটি এলিমেন্টের অন্তত একটি অনুভূমিক নিয়ম (alignParentLeft, toRightOf, centerHorizontal) এবং একটি উল্লম্ব নিয়ম (alignParentTop, below, centerVertical) থাকা আবশ্যক। যদি কোনো নিয়ম না থাকে, এলিমেন্টটি অবস্থান (0,0)-এ থাকে এবং অন্যান্য এলিমেন্টের নীচে বা স্ক্রিনের বাইরে লুকিয়ে থাকতে পারে। দ্বিতীয় কারণ হল একটি চক্রীয় নির্ভরতা (এলিমেন্ট A, B-এর সাথে সংযুক্ত, B, A-এর সাথে সংযুক্ত), যা অপ্রত্যাশিত আচরণের দিকে নিয়ে যায়।
অ্যাট্রিবিউট ব্যবহার করুন android:layout_centerInParent="true"। এটি এলিমেন্টটিকে উভয় অক্ষে একসাথে কেন্দ্রীভূত করে। যদি শুধু অনুভূমিকভাবে প্রয়োজন — android:layout_centerHorizontal="true", শুধু উল্লম্বভাবে — android:layout_centerVertical="true"। কেন্দ্রীভূতকরণ মার্জিনের সাথে সমন্বয়ে কাজ করে — এলিমেন্টটি নির্দিষ্ট অফসেট দ্বারা কেন্দ্রের সাপেক্ষে সরে যাবে।
হ্যাঁ, কিন্তু সুপারিশ করা হয় না। RelativeLayout চক্রীয় নির্ভরতার উপস্থিতিতে দুটি onMeasure পাস সম্পাদন করে, যা RecyclerView তালিকায় ConstraintLayout-এর তুলনায় 15–30% ধীর। RecyclerView আইটেম লেআউটের জন্য, ConstraintLayout ব্যবহার করুন — এটি ন্যূনতম মাপার সময় সহ একটি সমতল শ্রেণিবিন্যাস প্রদান করে। যদি RelativeLayout ইতিমধ্যে একটি লিগ্যাসি প্রকল্পে ব্যবহার করা হয়, নিশ্চিত করুন যে এলিমেন্টগুলি চক্রীয় নির্ভরতা তৈরি না করে, এবং Profile GPU Rendering-এর মাধ্যমে স্ক্রল FPS মাপুন।
android:layout_margin সব দিকে একসাথে মার্জিন সেট করে। android:layout_marginTop — শুধু উপরে। আরও নির্দিষ্ট অ্যাট্রিবিউট অগ্রাধিকার পায়: যদি উভয় layout_margin (16dp) এবং layout_marginTop (8dp) সেট করা থাকে, উপরের মার্জিন হবে 8dp। RelativeLayout-এ, মার্জিন কনস্ট্রেইন্টের সাপেক্ষে কাজ করে, সংলগ্ন এলিমেন্টের সাপেক্ষে নয়: layout_below="@id/target" সহ layout_marginTop হল এলিমেন্টের উপরের প্রান্ত থেকে target-এর নীচের প্রান্ত পর্যন্ত মার্জিন।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন