طراحی رابط کاربری در اندروید؛ از Layout تا Jetpack Compose
طراحی رابط کاربری (UI) یکی از مهمترین بخشهای توسعه اپلیکیشنهای اندرویدی است. تجربه نشان میدهد که کاربران تنها چند ثانیه پس از ورود به یک برنامه تصمیم میگیرند که آیا آن را ادامه دهند یا خیر. به همین دلیل، داشتن یک UI زیبا، روان، سازگار و استاندارد، به اندازه بخشهای فنی برنامه اهمیت دارد.
در اکوسیستم اندروید، طراحی رابط کاربری طی سالها تغییرات زیادی کرده و از XMLهای ساده تا معماری مدرن Jetpack Compose پیش رفته است. در این مقاله، از تاریخچه طراحی UI تا معرفی کامل Compose، مزایا، عملکرد، State Management و دستورات پایه آن را بررسی میکنیم.
برای نصب و راه اندازی ابزارهای برنامه نویسی اندروید با جزئیات بیشتر آموزش نصب و راه اندازی اندروید به مقاله ما مراجعه کنید.
روشهای طراحی رابط کاربری در اندروید
از ابتدای معرفی اندروید تاکنون، دو روش اصلی برای طراحی UI وجود داشته است:

۱) طراحی رابط کاربری با XML Layout (روش کلاسیک)
در این روش، فایلهای XML برای تعریف ساختار UI استفاده میشدند و برنامهنویس منطق برنامه را در فایلهای Kotlin/Java مینوشت.
این روش سالها در صنعت رایج بود و هنوز هم در بسیاری از پروژهها باقی مانده است.

۲) طراحی رابط کاربری با Jetpack Compose (روش مدرن)
Compose رویکرد جدید و دکلاراتیو گوگل برای طراحی UI است. در Compose دیگر نیازی به XML نیست و کل UI با استفاده از توابع Kotlin ایجاد میشود.
این روش سریعتر، سادهتر، قابل نگهداریتر و آیندهنگر است.

تاریخچه طراحی رابط کاربری در اندروید
نسل اول – Android XML Layouts (2008 تا 2015)
در اولین نسخههای اندروید، طراحی UI با فایلهای XML انجام میشد. ابزارها محدود بودند و بسیاری از UIها نیازمند کدنویسی دستی بودند.
نسل دوم – Material Design (2014)
با معرفی Material Design، گوگل یک زبان طراحی حرفهای ارائه داد.组件هایی مانند:
- AppBar
- FAB
- Navigation Drawer
- CardView
به UI اندروید جان تازهای بخشیدند.
نسل سوم – ConstraintLayout و ابزارهای پیشرفتهتر (2016)
ConstraintLayout معرفی شد تا مشکل لایههای تو در تو (Nested Layout) حل شود و عملکرد UI بهتر شود.
نسل چهارم – Jetpack Compose (2021 تا امروز)
Compose یک نقطه عطف بزرگ است. گوگل بهطور رسمی اعلام کرده است که آینده طراحی UI در اندروید «Compose» است و تمامی ابزارهای جدید حول آن توسعه داده میشوند.
لایوتها در اندروید (XML Layout)
XML Layout سالها ستون اصلی طراحی UI بود و شامل Layoutهای مختلفی است:

1) ConstraintLayout — سریع، منعطف و جایگزین مدرن برای RelativeLayout
چرا استفاده کنیم؟
ConstraintLayout طوری طراحی شده که با کمترین عمق درخت ویو (View Hierarchy) بیشترین انعطاف را بدهد. بهجای تو در تو بودن چندین لِیآوت، با Constraint میتوانید نسبتها، زنجیرها (chains)، و ترازها را مدیریت کنید که نتیجهاش عملکرد بهتر و نگهداری آسانتر است.
مزایا کلیدی
- حذف لایههای اضافی → در نتیجه کاهش هزینهٔ measure/layout
- بسیار انعطافپذیر؛ میتوانید هر ویویی را نسبت به هر ویوی دیگری یا والد position کنید
- پشتیبانی از Chains، Barriers، Guidelines، Percent positioning
- ابزار طراحی خوب در Android Studio (Layout Editor + Blueprint)
مثال ساده
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="عنوان"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:padding="16dp"/>
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ادامه"
app:layout_constraintTop_toBottomOf="@id/title"
app:layout_constraintEnd_toEndOf="@id/title"
android:layout_marginTop="16dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>
نکات پیشرفته / Best practices
- اگر عرض ویو را «پر» میکنید از
0dp(match_constraint) استفاده کنید تا اندازه به درستی محاسبه شود. - برای ردیفبندی همراستا از Chains استفاده کنید (
app:layout_constraintHorizontal_chainStyle="spread"). - برای اندازههای درصدی از
Guidelineیاapp:layout_constraintWidth_percent. - هنگام طراحی برای عملکرد، از attribute های
android:layout_با دقت استفاده کنید و از nested weights اجتناب کنید.
مواردی که نباید باهاش کرد
- استفادهٔ بیجا از تعداد زیاد Constraint با پیچیدگی بالا میتواند خوانایی کد را کم کند — در طراحی پیچیده بلوکها را تبدیل به reusable composable/view کنید.
2) LinearLayout — ساده، قابلفهم و برای چیدمانهای خطی بهترین است
چه زمانی استفاده کنیم؟
وقتی اجزا باید یکی بعد از دیگری بهصورت عمودی یا افقی قرار بگیرند و ساختار ساده است (مثلاً یک ستون فرم یا ردیف دکمهها).
ویژگیها
orientation="vertical"یا"horizontal"weightبرای تقسیم فضا بین فرزندان (layout_weight)- ساده و خوانا اما در صورت استفادهٔ نامناسب میتواند باعث nested layouts و افت کارایی شود.
مثال
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="عنوان"/>
<EditText android:layout_width="match_parent" android:layout_height="wrap_content"/>
<Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="ارسال"/>
</LinearLayout>
نکات عملی
- اگر نیاز به تو در تو کردن چند LinearLayout دارید، بهتر است از ConstraintLayout استفاده کنید تا عمق درخت ویو کاهش یابد.
- استفادهٔ مناسب از
layout_weight: وقتیwidthیاheightرا0dpمیگذارید و ازweightاستفاده میکنید عملکرد بهتر خواهد بود. - برای چیدمانهای ساده و خوانا LinearLayout عالی است؛ در فرمهای پیچیده آن را با Constraint جایگزین کنید.
3) RelativeLayout — قرارگیری ویوها نسبت به یکدیگر (قدیمیتر، اکنون کمتر توصیه میشود)
کاربرد
RelativeLayout به شما اجازه میدهد ویوها را نسبت به هم یا نسبت به والد قرار دهید (toRightOf, below, alignParentTop و غیره). قبل از ظهور ConstraintLayout، RelativeLayout جایگزین خوبی برای LinearLayoutهای تو در تو بود.
مثال
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/avatar"
android:layout_width="48dp"
android:layout_height="48dp"/>
<TextView
android:layout_toRightOf="@id/avatar"
android:layout_alignTop="@id/avatar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="نام کاربر"/>
</RelativeLayout>
چرا امروز کمتر ازش استفاده میشود؟
- ConstraintLayout تمام امکانات RelativeLayout را در قالبی بهینهتر و با قابلیتهای بیشتر ارائه میدهد.
- RelativeLayout در چیدمانهای پیچیده میتواند منجر به محاسبات هزینهبر شود.
نکات
- اگر پروژهٔ قدیمی دارید یا چیدمان خیلی ساده است میتوانید از RelativeLayout استفاده کنید؛ برای پروژههای جدید ConstraintLayout را ترجیح دهید.
4) FrameLayout — ساده برای Overlay و قرار دادن یک ویو روی دیگری
کاربرد اصلی
FrameLayout مناسب نمایش یک view روی دیگری است (مثلاً قرار دادن یک دکمه روی تصویر، یا نمایش loading spinner روی محتوا). معمولا تنها یک child اصلی دارد اما میتواند چندین ویو هم داشته باشد که به صورت لایهای (stacked) قرار میگیرند.
مثال استفاده برای Overlay
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/background"/>
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
</FrameLayout>
نکات عملی
- برای نمایش fragment معمولاً از FrameLayout بهعنوان container استفاده میشود.
- اگر نیاز به هماهنگی پیچیده بین لایهها دارید (behavior، scrolling) از CoordinatorLayout یا ConstraintLayout استفاده کنید.
- FrameLayout سبک و سریع است؛ وقتی فقط overlay لازم دارید بهترین انتخاب است.
5) ScrollView و RecyclerView — مدیریت لیستها و محتواهای طولانی
این دو لایوت اهداف متفاوتی ولی مرتبط دارند.
ScrollView
- برای محتواهایی که طولشان بیشتر از ارتفاع صفحه است و ساختار کاملاً استاتیک دارند (مثلاً صفحه قوانین طولانی، فرم طولانی).
- فقط یک child مستقیم میپذیرد (معمولاً LinearLayout که داخل آن چند view قرار میگیرد).
مثال
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- محتواهای طولانی -->
</LinearLayout>
</ScrollView>
محدودیتها
- برای لیستهای دادهمحور (مثلاً تعداد زیادی آیتم پویا) مناسب نیست چون همهٔ childها یکجا inflate میشوند و حافظه مصرفی زیاد میشود.
RecyclerView — برای لیستهای بزرگ و دینامیک
چرا RecyclerView؟
- طراحیشده برای لیستهای با آیتمهای زیاد
- ViewHolder pattern برای reuse ویوها → مصرف حافظه و CPU کمتر
- پشتیبانی از انواع LayoutManagerها (Linear, Grid, StaggeredGrid)
- قابل توسعه با DiffUtil, ItemDecoration, ItemAnimator و Pagination
نمونه ساده Adapter (کوتاهشده)
class MyAdapter(private val items: List<String>) : RecyclerView.Adapter<MyAdapter.VH>() {
class VH(itemView: View) : RecyclerView.ViewHolder(itemView) {
val text: TextView = itemView.findViewById(R.id.itemText)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
val v = LayoutInflater.from(parent.context).inflate(R.layout.item_row, parent, false)
return VH(v)
}
override fun onBindViewHolder(holder: VH, position: Int) {
holder.text.text = items[position]
}
override fun getItemCount() = items.size
}
نکات بهبود عملکرد
- از
ListAdapter+DiffUtilبرای بهروزرسانیهای هوشمند استفاده کنید. - از
setHasFixedSize(true)وقتی اندازه آیتمها ثابت است. - بارگذاری تصاویر را به صورت async با Glide/Coil انجام دهید و placeholder تعریف کنید.
- از ViewPool برای RecyclerViewهای تو در تو استفاده کنید.
چه زمانی از RecyclerView استفاده نکنیم؟
- وقتی فقط چند view ثابت دارید که تعدادشان کم است — در این حالت ScrollView یا LinearLayout ساده بهتر است.
XML همچنان در بسیاری از پروژههای قدیمی استفاده میشود، اما در پروژههای جدید Compose جایگزین آن شده است.
برای نصب و راه اندازی ابزارهای برنامه نویسی اندروید با جزئیات بیشتر آموزش نصب و راه اندازی اندروید به مقاله ما مراجعه کنید.
Jetpack Compose در اندروید؛ نسل جدید UI
Jetpack Compose شیوه طراحی رابط کاربری را دگرگون کرده است. Compose یک سیستم دکلاراتیو، واکنشگرا و مبتنی بر Kotlin است که نیاز به XML را کاملاً حذف میکند.

مثال ساده
@Composable
fun Greeting(name: String) {
Text("سلام $name!")
}
مزایای استفاده از Compose
⭐ مزایای استفاده از Jetpack Compose
✔ ۱. بدون نیاز به XML
یکی از بزرگترین مزایای Compose حذف کامل فایلهای XML است. در روش قدیمی، طراحی UI در XML و منطق برنامه در Kotlin/Java نوشته میشد و گاهی هماهنگکردن این دو بخش باعث پیچیدگی، خطا و دوبارهکاری میشد.
اما در Compose، تمام رابط کاربری فقط با Kotlin نوشته میشود؛ یعنی UI و Logic کاملاً در یک لایه قرار میگیرند. این ساختار یکپارچه باعث میشود:
- کدنویسی روانتر شود
- نیاز به Sync بین XML و کد از بین برود
- ساختار پروژه تمیزتر و قابل نگهداریتر باشد
Compose درواقع UI را از دل کد میسازد و نیازی به هیچ فایل جداگانهای وجود ندارد.
✔ ۲. سرعت توسعه ۲ تا ۳ برابر بیشتر
Jetpack Compose بهطور چشمگیری سرعت ساخت رابط کاربری را افزایش میدهد.
در روش سنتی شما باید:
- برای هر ویو ID تعریف کنید
- از
findViewByIdیا ViewBinding استفاده کنید - برای RecyclerView، Adapter و ViewHolder بسازید
- برای هر تغییر کوچک اپلیکیشن را Build کنید
اما در Compose این مراحل حذف شده است. فقط کافی است از توابع Composable استفاده کنید و UI بهصورت مستقیم ایجاد میشود. همچنین کامپوننتهایی مثل LazyColumn جایگزین RecyclerView شده و بسیاری از کدهای اضافی حذف میشود. نتیجه این است که:
- حجم کد کمتر میشود
- زمان توسعه کاهش مییابد
- خطاهای UI کمتر رخ میدهد
چرا؟ چون Compose بخش زیادی از فرایندهای پیچیده را خودکار و هوشمند مدیریت میکند.
✔ ۳. مدیریت State آسان و کاملاً واکنشگرا
Compose یک سیستم Reactive است؛ یعنی UI همیشه بهصورت خودکار از روی State ساخته میشود.
در XML، تغییرات UI باید دستی اعمال میشدند (setText، setVisibility، notifyDatasetChanged و …). این فرآیندها زمانبر و مستعد خطا بودند.
اما در Compose:
- UI = تابعی که خروجیاش وابسته به State است
- هر زمان State عوض شود، UI خودش رفرش میشود
- نیازی به هیچ مدیریت دستی وجود ندارد
این ویژگی باعث میشود UI همیشه «همزمان با داده» باشد و هیچ تعارضی بین منطق و نمایش اتفاق نیفتد.
✔ ۴. سازگاری کامل با Material Design 3
Compose بهصورت بومی با Material Design 3 (نسخه جدید زبان طراحی گوگل) سازگار است.
تمام کامپوننتهای مدرن از جمله:
- Buttonهای جدید
- کارتها (Card)
- Navigation Bar و Navigation Rail
- TextFieldهای جدید
- سیستم رنگبندی پویا (Dynamic Color)
- Shadow، Elevation و Typography جدید
در Compose بهطور کامل پشتیبانی میشوند. مهمتر از آن اینکه گوگل تمام اجزای جدید Material Design را ابتدا برای Compose منتشر میکند و XML دیگر اولویت اصلی نیست.
به همین دلیل برای طراحی UI مدرن و مطابق استانداردهای جدید، Compose بهترین انتخاب است.
✔ ۵. Preview زنده (Live Preview) بدون اجرای اپلیکیشن
Compose قابلیت خارقالعادهای به نام Live Preview دارد.
در XML پیشنمایش همیشه دقیق نبود و برای بسیاری از تغییرات باید اپلیکیشن را Build و اجرا میکردید.
اما در Compose:
- میتوانید UI را بدون اجرا شدن اپ ببینید
- در لحظه تغییرات را مشاهده کنید
- حتی چند حالت مختلف (Dark Mode، چند زبان، اندازه صفحههای مختلف) را همزمان Preview کنید
این ویژگی سرعت طراحی UI را چندین برابر افزایش میدهد و باعث میشود چرخه طراحی، تعریف و تست بسیار کوتاه شود.
✔ ۶. قابلیت استفاده در پروژههای موجود (Hybrid UI)
Compose کاملاً قابل ترکیب با XML است. یعنی اگر پروژه قدیمی دارید لازم نیست از صفر دوباره آن را بنویسید.
میتوانید:
➤ از Compose داخل XML استفاده کنید
با ComposeView
➤ از XML داخل Compose استفاده کنید
با AndroidView
این ویژگی باعث میشود:
- مهاجرت به Compose تدریجی و بدون ریسک باشد
- در پروژههای بزرگ، بخشهای جدید با Compose نوشته شوند
- وابستگی پروژه به XML بهمرور کم شود
به عبارت دیگر، Compose تحمیلگر نیست؛ بلکه کاملاً انعطافپذیر است.

چرا گوگل از XML Layout به Compose مهاجرت کرد؟
گوگل دلایل مختلفی برای این مهاجرت دارد:
✔ ۱. پیچیدگی بالا و مدیریت دشوار XML
XML دارای محدودیتهایی بود که توسعه و نگهداری UI را کند میکرد.
✔ ۲. بهبود Performance
برای رندر کردن ویوهای تودرتو، اندروید باید لایههای زیادی را پردازش میکرد.
✔ ۳. رقابت با SwiftUI اپل
اپل SwiftUI را منتشر کرد و این باعث شد گوگل Compose را جدیتر توسعه دهد.
✔ ۴. معماری مدرن و Reactive
Compose مشابه React Native، Flutter و SwiftUI است؛ یعنی UI را بر اساس State میسازد.
✔ 5. افزایش سرعت توسعه و کاهش خطا
Compose نیاز به boilerplate کمتری دارد و برنامهنویس سریعتر نتیجه میگیرد.
Performance طراحی رابط کاربری با Compose
برخلاف تصور بعضی افراد، Compose بسیار سریع و بهینه است.
دلایل:
✔ ۱. حذف لایههای اضافه (No View Hierarchy)
Compose ویوهای سنگین XML را ندارد.
✔ ۲. رندر هوشمند
فقط بخشی که State آن تغییر کرده rerender میشود.
✔ ۳. استفاده از Skia Engine
همان موتور گرافیکی فلاتر که سرعت بسیار بالایی دارد.
✔ ۴. بهتر از ConstraintLayout در برخی موارد
در لیستها و UIهای داینامیک، Compose عملکرد بهتری دارد.

آشنایی با Stateها در Compose
Compose یک فریمورک Reactive است، یعنی UI مستقیماً بر اساس State ساخته میشود.
State هر زمان تغییر کند، UI تغییر میکند.
⭐ مثال ساده از State
@Composable
fun Counter() {
var count by remember { mutableStateOf(0) }
Column {
Text("Count: $count")
Button(onClick = { count++ }) {
Text("افزایش")
}
}
}
Stateهای مهم در Compose:
- mutableStateOf → برای نگهداری دادهها
- remember → نگهداری State در Composable
- rememberSaveable → حفظ State بعد از چرخش صفحه
- StateFlow / LiveData → مدیریت State در ViewModel

آموزش دستورات پایه Compose در اندروید
۱. Text
Text(text = "سلام اندروید!")

۲. Button
Button(onClick = { /* TODO */ }) {
Text("کلیک کن")
}

۳. Column و Row
Column {
Text("عنوان")
Text("متن توضیحات")
}

۴. Image
Image(
painter = painterResource(R.drawable.logo),
contentDescription = "لوگو"
)

۵. LazyColumn (لیستها)
جایگزین RecyclerView
LazyColumn {
items(20) { index ->
Text("آیتم شماره $index")
}
}
۶. Modifier
ابزار اصلی برای سایز، پدینگ، بکگراند:
Text(
"نمونه متن",
modifier = Modifier
.padding(16.dp)
.background(Color.LightGray)
)

جمعبندی
طراحی رابط کاربری در اندروید طی سالها تکامل بزرگی داشته است. از XML Layoutهای کلاسیک گرفته تا معماری مدرن Jetpack Compose، ابزارها هر روز سادهتر، سریعتر و قدرتمندتر شدهاند.
امروزه Compose بهعنوان استاندارد اصلی طراحی UI در اندروید شناخته میشود و گوگل همهٔ تمرکز خود را روی توسعهٔ این ابزار قرار داده است.
اگر قصد دارید در برنامهنویسی اندروید حرفهای باشید، یادگیری Compose یک سرمایهگذاری بلندمدت و ضروری است.
دیدگاهتان را بنویسید