LinearLayout-এর মৌলিক বিষয় ব্যাখ্যা করছি — Android SDK-এ একটি মৌলিক ViewGroup যা চাইল্ড এলিমেন্টগুলিকে এক লাইনে সাজায়: উল্লম্বভাবে (LinearLayout.VERTICAL) বা অনুভূমিকভাবে (LinearLayout.HORIZONTAL)। LinearLayout এখনও বাটনের সারি, সেটিংস তালিকা বা ইনপুট ফর্ম তৈরি করার সবচেয়ে সহজ এবং দ্রুততম উপায় যখন লেআউটের জটিলতা 5–10 এলিমেন্টের বেশি না হয়। layout_weight এবং orientation অ্যাট্রিবিউটগুলি স্থান বিতরণ এবং দিকনির্দেশনা পরিচালনা করে। বিস্তারিত স্পেসিফিকেশন — LinearLayout API Reference-এ।
মূল বিষয়
LinearLayout — Android SDK (API Level 1)-এর প্রথম ViewGroups-এর একটি, যা চাইল্ড এলিমেন্টগুলিকে ক্রমান্বয়ে এক সারি বা কলামে রাখার জন্য ডিজাইন করা হয়েছে। প্রতিটি নতুন এলিমেন্ট আগেরটির পরে অবস্থান করে, এবং দিকনির্দেশনা android:orientation অ্যাট্রিবিউট দ্বারা নির্ধারিত হয়। LinearLayout হল সবচেয়ে সহজ এবং পূর্বানুমানযোগ্য Android কন্টেইনার, যা এটিকে লিনিয়ার ইন্টারফেসের জন্য আদর্শ পছন্দ করে তোলে: বাটনের সারি, আইকন এবং টেক্সট-সহ সেটিংস তালিকা, অনুভূমিক মেনু।
ঐতিহাসিকভাবে, LinearLayout হল প্রথম ViewGroup যা একজন শিক্ষানবিশ Android ডেভেলপার জানতে পারেন। এর সুবিধা হল স্বচ্ছতা: চাইল্ড এলিমেন্টগুলি লুকানো পজিশনিং নিয়ম ছাড়াই ঘোষণার ক্রমে কঠোরভাবে স্থাপন করা হয়। RelativeLayout-এর বিপরীতে, যেখানে একটি এলিমেন্ট যেকোনো প্রতিবেশীর সাথে যুক্ত হতে পারে, বা ConstraintLayout তার কনস্ট্রেইন্ট সিস্টেম সহ, LinearLayout "প্রথম বাম/উপরে, তার পরে দ্বিতীয়, দ্বিতীয়টির পরে তৃতীয়" নীতিতে কাজ করে। Google I/O 2017 অনুযায়ী, Google Play-এর শীর্ষ 1000 অ্যাপের 78% স্ক্রিন LinearLayout-কে তাদের প্রধান বা সহায়ক কন্টেইনার হিসেবে ব্যবহার করে।
LinearLayout-এর প্রধান মেট্রিক হল LinearLayout.MeasureSpec — আকার ব্যবস্থাপনা সিস্টেম। VERTICAL ওরিয়েন্টেশনের সাথে, প্রতিটি এলিমেন্টের প্রস্থ প্যারেন্টের প্রস্থের (match_parent বা ফিক্সড) সমান, এবং উচ্চতা কন্টেন্ট বা অ্যাট্রিবিউট দ্বারা নির্ধারিত হয়। HORIZONTAL-এর জন্য এর বিপরীত: উচ্চতা প্যারেন্টের সমান, প্রস্থ কন্টেন্ট অনুযায়ী। যদি HORIZONTAL সারিতে মোট এলিমেন্টের প্রস্থ প্যারেন্টের প্রস্থ অতিক্রম করে, তাহলে এলিমেন্টগুলি স্ক্রিনের বাইরে চলে যেতে পারে (যদি weight ব্যবহার না করা হয়)।
LinearLayout ViewGroup থেকে onMeasure এবং onLayout ওভাররাইড করে। VERTICAL ওরিয়েন্টেশনের সাথে, onLayout Y অক্ষ বরাবর এলিমেন্ট স্থাপন করে: প্রথম চাইল্ড — y=0, দ্বিতীয় — y=prev.bottom + divider.hidden, এবং আরও। HORIZONTAL-এর সাথে — X অক্ষ বরাবর। Divider android:divider এবং android:showDividers (beginning, middle, end)-এর মাধ্যমে নির্ধারিত হয়। Divider একটি রঙ, drawable বা কাস্টম Shape রিসোর্স হতে পারে।
ওরিয়েন্টেশন — LinearLayout-এর একটি গুরুত্বপূর্ণ অ্যাট্রিবিউট যা চাইল্ড এলিমেন্ট স্থাপনের দিকনির্দেশনা নির্ধারণ করে। android:orientation="vertical" এলিমেন্টগুলিকে উপরে থেকে নীচে সাজায়; android:orientation="horizontal" — বাম থেকে ডানে (বা RTL লোকালাইজেশনের সাথে ডান থেকে বামে)। যদি ওরিয়েন্টেশন নির্ধারিত না হয়, তাহলে ডিফল্টভাবে HORIZONTAL ব্যবহার করা হয় (পুরনো সংস্করণে) — কিন্তু পূর্বানুমানযোগ্য আচরণের জন্য স্পষ্ট উল্লেখ প্রয়োজন।
android:gravity — LinearLayout-এর ভিতরে কন্টেন্ট সাজায়। কম্বিনেশন গ্রহণ করে: top, bottom, left, right, center, center_horizontal, center_vertical, fill, clip_vertical, clip_horizontal। VERTICAL লেআউটের জন্য gravity="center" মান সমস্ত এলিমেন্টকে অনুভূমিকভাবে কেন্দ্রীভূত করবে। android:layout_gravity — একটি চাইল্ড এলিমেন্ট অ্যাট্রিবিউট যা এটিকে প্যারেন্ট LinearLayout-এর ভিতরে সাজায়। উদাহরণ: VERTICAL লেআউটে layout_gravity="right"-সহ একটি বাটন বাটনটিকে ডান প্রান্তে ঠেলে দেবে।
পার্থক্য: gravity — প্যারেন্টের বৈশিষ্ট্য (চিল্ড্রেন এর ভিতরে কীভাবে সাজানো হয়), layout_gravity — চাইল্ডের বৈশিষ্ট্য (এটি প্যারেন্টের ভিতরে কীভাবে আচরণ করে)। এই অ্যাট্রিবিউটগুলি গুলিয়ে ফেলা শিক্ষানবিশদের সবচেয়ে সাধারণ ভুলগুলির মধ্যে একটি।
টেক্সট এলিমেন্ট (TextView, Button, EditText)-সহ HORIZONTAL লেআউটের জন্য, android:baselineAligned="true" উপকারী — এটি প্যাডিং, সাইজ বা উচ্চতা নির্বিশেষে সমস্ত টেক্সটকে ফন্ট বেসলাইন দ্বারা সাজায়। এটি একটি আইকন, শিরোনাম এবং বিবরণ-সহ সারিটিকে দৃশ্যত পরিষ্কার করে: টেক্সট উপরে-নীচে লাফায় না।
layout_weight — LinearLayout-এর একটি চাইল্ড এলিমেন্ট অ্যাট্রিবিউট যা নির্ধারণ করে এটি খালি স্থানের কত অংশ নেবে। এটি শুধুমাত্র ওরিয়েন্টেশনের দিকেই কাজ করে (HORIZONTAL-এর জন্য প্রস্থ, VERTICAL-এর জন্য উচ্চতা)। গণনা সূত্র: আকার = নিজস্ব আকার + (খালি স্থান × (এলিমেন্টের ওজন / সমস্ত ওজনের যোগফল))। খালি স্থান = প্যারেন্টের আকার — সমস্ত চাইল্ডের নিজস্ব আকারের যোগফল।
layout_weight অভিযোজিত ইন্টারফেসের জন্য ফিক্সড আকারের চেয়ে বেশি কার্যকর। উদাহরণস্বরূপ, যদি বাম প্যানেলটি স্ক্রিনের 30% এবং ডান প্যানেলটি 70% দখল করা উচিত, তাহলে weight=3 এবং weight=7 সেট করুন। সঠিক অপারেশনের জন্য, দিকের আকার সাধারণত 0dp-তে সেট করা হয় (android:layout_width="0dp" HORIZONTAL-এর জন্য), তাহলে এলিমেন্টের নিজস্ব আকার শূন্য গণ্য হয়, এবং সম্পূর্ণ আকার শুধুমাত্র weight দ্বারা নির্ধারিত হয়। এটি মানক Google সুপারিশ (Android Developers Guide, 2024)।
গুরুত্বপূর্ণ: ওজনগুলি LinearLayout-এর সমস্ত এলিমেন্টের জন্য যোগ করা হয়, যার মধ্যে যাদের weight সেট নেই তাদেরও (তাদের ওজন 0 গণ্য হয়)। যদি একটি এলিমেন্টের weight=1 এবং অন্যটির weight=2 হয়, তাহলে প্রথমটি খালি স্থানের 1/3 নেবে, দ্বিতীয়টি — 2/3। weightSum (প্যারেন্টের একটি অ্যাট্রিবিউট) সর্বোচ্চ ওজনের যোগফল সেট করার অনুমতি দেয় — যদি চাইল্ডের ওজনের যোগফল weightSum-এর চেয়ে কম হয়, তাহলে পার্থক্যটি খালি স্থান থাকে।
লগইন ফর্মটি তিনটি এলিমেন্ট নিয়ে গঠিত: ইমেইল ফিল্ড (স্ক্রিন উচ্চতার 2/4), পাসওয়ার্ড ফিল্ড (1/4) এবং বাটন (1/4)। weight-সহ তিনটি এলিমেন্টই শুধুমাত্র VERTICAL ওরিয়েন্টেশনে উচ্চতা অনুযায়ী কাজ করে।
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<EditText
android:id="@+id/email"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:hint="Email" />
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:hint="পাসওয়ার্ড"
android:inputType="textPassword" />
<Button
android:id="@+id/login_button"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="লগ ইন করুন" />
</LinearLayout>
প্রতিটি এলিমেন্টের উচ্চতা = (parent_height — padding) × (weight / sumWeights)। email উচ্চতার 2/4 পায়, পাসওয়ার্ড এবং বাটন — প্রতিটি 1/4। সবগুলো height=0dp, তাই নিজস্ব আকার বিবেচনা করা হয় না — শুধুমাত্র weight কাজ করে।
তিনটি বাটন-সহ একটি প্যানেল: ব্যাক আইকন (wrap_content), শিরোনাম (বাকি অংশ পূরণ) এবং মেনু আইকন (wrap_content)। শিরোনামের জন্য weight=1, বাটনগুলি weight ছাড়া।
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="56dp"
android:gravity="center_vertical">
<ImageButton
android:id="@+id/btn_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_arrow_back" />
<TextView
android:id="@+id/toolbar_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="শিরোনাম"
android:textSize="18sp" />
<ImageButton
android:id="@+id/btn_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_more_vert" />
</LinearLayout>
ব্যাক এবং মেনু বাটনগুলি আইকনের জন্য যতটুকু প্রয়োজন ঠিক ততটুকু স্থান নেয়। width=0dp এবং weight=1-সহ শিরোনাম (TextView) তাদের মধ্যে বাকি সমস্ত স্থানে প্রসারিত হয়। gravity="center_vertical" সমস্ত এলিমেন্টকে উল্লম্বভাবে কেন্দ্রীভূত করে।
একটি পণ্য কার্ড: অনুভূমিক সারি (ছবি + উল্লম্ব টেক্সট ব্লক)। বাইরের LinearLayout HORIZONTAL, ভিতরের — শিরোনাম, বিবরণ এবং মূল্যের জন্য VERTICAL।
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:src="@drawable/product_image"
android:scaleType="centerCrop" />
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="12dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="পণ্যের নাম"
android:textStyle="bold"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="দুই লাইনে সংক্ষিপ্ত পণ্য বিবরণ"
android:textSize="14sp"
android:textColor="@color/gray" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="১,২৯৯ RUB"
android:textSize="18sp"
android:textColor="@color/accent" />
</LinearLayout>
</LinearLayout>
বাম দিকে ছবি (80×80dp), ডান দিকে — তিনটি টেক্সট লাইনের উল্লম্ব ব্লক। ভিতরের LinearLayout-এর weight=1, তাই এটি ছবির পরে বাকি সমস্ত স্থান দখল করে। এটি একটি ক্লাসিক তালিকা কার্ড প্যাটার্ন যা হাজার হাজার অ্যাপে পাওয়া যায়।
LinearLayout-এর প্রধান ত্রুটি — জটিল লেআউটের জন্য নেস্টেড কন্টেইনারের প্রয়োজন। যদি আপনার এলিমেন্টগুলিকে 2×2 গ্রিডে সাজাতে বা উভয় প্রান্তে সাজানো-সহ একটি সারি তৈরি করতে হয়, তাহলে কমপক্ষে 2–3টি নেস্টিং স্তর প্রয়োজন। প্রতিটি LinearLayout স্তর 2টি onMeasure পাস যোগ করে, যা দুর্বল ডিভাইসে রেন্ডারিংয়ের সময় লক্ষণীয় ব্যবধানের কারণ হয়।
Android Performance Blog (Google, 2017) অনুযায়ী, প্রতিটি অতিরিক্ত নেস্টিং স্তর লেআউট সময় 30–50 μs বাড়ায়। 3টি নেস্টিং স্তর-সহ 20টি আইটেমের তালিকার জন্য, বিলম্ব প্রতি এলিমেন্টে 3 ms পর্যন্ত পৌঁছাতে পারে — এটি স্ক্রোল করার সময় লক্ষণীয় jank। ConstraintLayout একটি সমতল শ্রেণিবিন্যাসের মাধ্যমে এই সমস্যার সমাধান করে, 3–4টি নেস্টেড LinearLayout-কে একটি একক কনস্ট্রেইন্ট কন্টেইনার দিয়ে প্রতিস্থাপন করে।
সুপারিশ: সাধারণ লিনিয়ার লেআউটের জন্য (10টি এলিমেন্ট পর্যন্ত, একটি নেস্টিং স্তর) LinearLayout ব্যবহার করুন। তালিকা কার্ড, বিভিন্ন সাজানো-সহ ফর্ম এবং টেবিল কাঠামো-সহ স্ক্রিনের জন্য ConstraintLayout বেছে নিন। RecyclerView-এ পুনরাবৃত্ত এলিমেন্টের জন্য, আইটেম লেআউট ফাইলে ConstraintLayout ব্যবহার করুন — এটি স্ক্রোল পারফরম্যান্সের জন্য গুরুত্বপূর্ণ।
সচরাচর জিজ্ঞাস্য
সবচেয়ে সাধারণ কারণ — দিকের আকার 0dp-তে সেট করা নেই। HORIZONTAL লেআউটের জন্য android:layout_width="0dp" প্রয়োজন, VERTICAL-এর জন্য — android:layout_height="0dp"। যদি এলিমেন্টের wrap_content বা match_parent থাকে, তাহলে weight কাজ নাও করতে পারে বা অপ্রত্যাশিত ফলাফল দিতে পারে। দ্বিতীয় কারণ — প্যারেন্টে weightSum চাইল্ডের ওজনের যোগফলের চেয়ে কম। তৃতীয় — বিপরীত দিকে চাইল্ড এলিমেন্টে match_parent ব্যবহার করা।
layout_weight প্রতিটি চাইল্ড এলিমেন্টে সেট করা হয় এবং খালি স্থানে তার অংশ নির্ধারণ করে। weightSum — প্যারেন্ট LinearLayout-এর একটি অ্যাট্রিবিউট যা সর্বোচ্চ ওজনের যোগফল সেট করে। ডিফল্টভাবে, weightSum = সমস্ত চাইল্ডের layout_weight-এর যোগফল। আপনি যদি weightSum = 3 সেট করেন, এবং চাইল্ডের weight=1 থাকে, তাহলে প্রতিটি 1/3 দখল করবে। যদি weight=1-সহ মাত্র দুটি চাইল্ড থাকে, তাহলে বাকি 1/3 খালি থাকবে। এলিমেন্ট যোগ/মুছে ফেলার সময় পুনঃগণনা ছাড়াই অনুপাত স্থির করার জন্য weightSum সুবিধাজনক।
ডিফল্টভাবে কোনও ফাঁক নেই — এলিমেন্টগুলি সংলগ্নভাবে স্থাপিত হয়। যদি ফাঁক দেখা দেয়, তাহলে পরীক্ষা করুন: প্যারেন্টে android:divider এবং android:showDividers, চাইল্ড এলিমেন্টে android:layout_margin। অতিরিক্তভাবে, android:weightSum প্রভাব ফেলতে পারে — যদি এলিমেন্টগুলি weight ব্যবহার করে, তাহলে ভুল গণনার কারণে তাদের মধ্যে খালি স্থান থাকতে পারে। শূন্য ফাঁকের জন্য, সমস্ত চাইল্ড মার্জিন 0dp-তে সেট করুন এবং divider সরান।
সরল এক-দিকনির্দেশক লেআউটের জন্য (এক সারি/কলামে 1–5 এলিমেন্ট) LinearLayout সামান্য দ্রুত — এটি কনস্ট্রেইন্ট গণনায় সম্পদ খরচ করে না। জটিল লেআউটের জন্য (5টির বেশি এলিমেন্ট, গ্রিড, বিভিন্ন ধরনের সাজানো) ConstraintLayout দ্রুত কারণ এটি নেস্টেড LinearLayout-এর পরিবর্তে একটি সমতল শ্রেণিবিন্যাস ব্যবহার করে। Google পরীক্ষা (Android Performance Blog) অনুযায়ী, ConstraintLayout সেই লেআউটগুলিতে জেতে যেখানে 3+ স্তরের LinearLayout নেস্টিং প্রয়োজন।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন