طراحی صفحات با ConstraintLayout + سورس پروژه
در جلسه قبل با عنوان آموزش طراحی رابط کاربری در اندروید با کلیات رابط کاربری، ویو، ویجتها و همچنین لایه (Layout یا ViewGroup) های پرکاربرد LinearLayout و RelativeLayout آشنا شدیم. در این جلسه قصد داریم طراحی صفحات با ConstraintLayout را بررسی کنیم.
این layout که نسبت به سایر layout های اندروید عمر کمتری دارد، از انعطاف بسیار بالاتری برخوردار بوده و میتواند زمان طراحی و حجم کدهای xml رابط کاربری اکتیویتی را تا حد زیادی کاهش دهد. در نتیجه با کاهش حجم کدها، سرعت نمایش صفحات افزایش یافته و میتوانیم شاهد بهبود عملکرد کلی اپلیکیشن باشیم.
در صورتی که با ویژگیها و امکانات به خوبی آشنا بوده و به اندازه کافی روی این ViewGroup جدید تمرینات مختلف انجام داده باشیم، احتمالا در اکثر موارد میتوانیم بدون بکارگیری لایههای LinearLayout، RelativeLayout، FrameLayout، TableLayout و GridLayout رابطهای کاربری مدنظر خود را در بهینهترین حالت ممکن پیاده سازی کنیم.
در این جلسه سعی میکنم تمامی قابلیتها و جزئیات این layout تازه نفس را در قالب مثال بیان کنم. توجه داشته باشید این آموزش به نوعی ادامهی جلسه آموزش طراحی رابط کاربری در اندروید بوده و پیش نیاز این جلسه، آشنایی با مفاهیم ابتدایی رابط کاربری میباشد که قبلا به آنها پرداختهایم.
- ConstraintLayout چیست؟
- نحوه طراحی صفحات رابط کاربری اندروید با ConstraintLayout
- خطوط اتصال و گرهها در ConstraintLayout
- تعیین فاصله از چپ و پایین توسط Bias
- تعیین عرض و ارتفاع Widget یا View ها
- حذف یکباره تمامی Constraint ها
- تبدیل ViewGroup های دیگر به ConstraintLayout
- ایجاد خودکار Constraint ها
- تعیین فاصله یا Margin پیش فرض
- همتراز کردن ویجتهای متنی توسط Baseline
- همتراز کردن ویجتها در جهت افقی یا عمودی
- ایجاد فاصله یکسان بین View ها با استفاده از Chain
- پیاده سازی استایلهای مختلف برای Chain
- کاربرد گزینه Autoconnection to Parent
- کاربرد گزینههای Pack و Expand
- اتصال خودکار ویجتها توسط Distribute
- کاربرد گزینههای Edges
- تنظیم خودکار Baseline ها
- تراز کردن View ها توسط Guideline یا خط راهنما
- تعیین محدوده متغیر برای چند ویجت توسط Barrier
- نمایش، حذف یا مخفی کردن چندین View توسط Group
- تغییر چیدمان ویجتها بر اساس اندازه صفحه نمایش توسط Flow
- جابجایی چند ویجت به صورت گروهی توسط Layer
این جلسه در قالب PDF و در ۱۰۷ صفحه تهیه شده که در ادامه چند صفحه ابتدایی را مشاهده میکنید:
ConstraintLayout چیست؟
به نام خدا. ConstraintLayout برای اولین بار در کنفرانس Google I/O در سال ۲۰۱۶ معرفی شد. اصلی ترین هدف گوگل از معرفی این Layout جدید، امکان طراحی لایههای پیچیده و در عین حال flat (تخت) بود؛ بر خلاف Layout های قبلی که برای طراحی یک صفحه ناگزیر به استفاده از لایههای تو در تو و سلسله مراتبی بودیم.
این یعنی دیگر لازم نیست چندین لایه RelativeLayout و LinearLayout و… درون یکدیگر و به صورت تو در تو تعریف شود تا بتوان یک صفحه چند قسمتی را ساخت. بنابراین علاوه بر سادگی پیاده سازی این لایه و کاهش حجم نهایی کدهای آن، در طراحی صفحات با ConstraintLayout کارایی و performance اکتیویتی بهبود یافته و میتواند در افزایش سرعت نمایش UI روی دستگاه کاربر تاثیر مثبت بگذارد.
ConstraintLayout از اندروید استودیو ۲٫۲ اضافه شد و نسخه ابتدایی آن Beta 1 نام داشت. در طی این چند سال مرتبا اصلاحاتی روی آن انجام و همچنین قابلیتهای جدیدی نیز اضافه شده است. خبر خوب اینکه این لایه از API 9 به بعد پشتیبانی میشود بنابراین مطمئن خواهیم بود تمامی دستگاههای اندرویدی که در حال حاضر در اختیار افراد هست به خوبی میتوانند صفحاتی که با این layout طراحی شدهاند را نمایش دهند.
در ConstraintLayout میتوانیم وضعیت قرارگیری تمامی view/widget ها را نسبت به یکدیگر و یا parent شان تعیین کنیم. برای مثال میتوانیم یک TextView را به نحوی در زیر یک ImageView متصل کنیم که در جهت افقی، متن همواره در مرکز تصویر قرار گیرد. یا اینکه یک یا چند view بر اساس سایز صفحه نمایش دستگاه، چه از جهت افقی و چه عمودی همواره در مرکز قرار گرفته و علاوه بر آن، فاصله آنها از یکدیگر نیز درصدی ثابت باشد.
این یعنی یک انعطاف پذیری بسیار بالا که تا حدود زیادی مشابه طراحی صفحات واکنشگرا یا Responsive در صفحات وب است.
فکر میکنم هرچه اینجا بیشتر توضیح بدهم بیشتر هم شما را گیج میکنم! بنابراین بهتر است سراغ محیط توسعه اندروید استودیو رفته و امکانات این لایه قدرتمند را در عمل بررسی کنیم.
توجه داشته باشید در نسخههای ابتدایی اندروید استودیو که ConstraintLayout اضافه شده بود میبایست ابزار آن به صورت جداگانه در SDK و در زیرمجموعه Support Repository دریافت و نصب میشد اما در نسخههای اخیر، این گزینه از لیست SDK Tools حذف شده و با سایر ابزار اصلی توسعه اندروید ادغام شده است.
قبل از هرچیز توجه داشته باشید در برخورد اول قطعا کار با این layout مقداری گیج کننده خواهد بود بنابراین لازم است بارها و بارها تمرین کرده و خروجی کار را مقایسه کنید تا کاربرد هر قابلیت را بتوانید به درستی درک نمائید.
نحوه طراحی صفحات رابط کاربری اندروید با ConstraintLayout
قبل از هرچیز ابتدا طبق مبحث آموزش ساخت پروژه در اندروید استودیو یک پروژه اندرویدی با نام ConstraintLayout میسازم. اکتیویتی را از نوع Empty Activity و زبان را Java انتخاب کردم.
کتابخانه این layout به صورت پیش فرض در بلاک dependencies فایل build.gradle(app) پروژه اندرویدی قرار دارد:
dependencies { implementation 'androidx.constraintlayout:constraintlayout:2.0.4' }
در زمان نگارش این آموزش، نسخه ۲٫۰٫۴ جدیدترین نسخه از این ViewGroup است.
Layout پیش فرض اکتیویتی پروژه از نوع ConstraintLayout بوده که در قسمت Component tree قابل مشاهده است:
محیط پیش نمایش در دو حالت Design و Blueprint قابل نمایش است که به منظور خلوت بودن صفحه در حین آموزش تنها از حالت Design استفاده میکنم.
خطوط اتصال و گرهها در ConstraintLayout
از ساده ترین مثال شروع میکنم. ملاحظه میکنید یک TextView به طور پیش فرض در مرکز صفحه پیش نمایش با عنوان Hello World! قرار گرفته. موس را روی TextView قرار میدهم:
این TextView توسط ۴ خط اتصال به ۴ لبهی صفحه متصل شده است. حالا روی TextView کلیک میکنم:
ملاحظه میکنید خطوط اتصال پررنگ شده و نقاط اتصال خطوط به ویجت مدنظر نیز به شکل دایرههای توپر نمایش داده میشود. هر کدام از این دایرهها را یک گره یا node مینامیم. علت قرار گرفتن این TextView در مرکز صفحه این است که هر ۴ گره آن به چهار جهت صفحه نمایش متصل شده.
قبل از انجام هر کاری کد xml صفحه را بررسی میکنیم:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
ملاحظه میکنید یک TextView با تعدادی ویژگی درون layout از جنس ConstraintLayout قرار گرفته است. به عبارتی این layout والد یا parent ویجت TextView است.
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent"
این چهار attribute موقعیت مکانی TextView را نسبت به والد خود تعیین میکند. یعنی به ازاء هر خط اتصالی که از گرههای ویجت به یکی از کنارههای صفحه نمایش کشیده شده یکی از این ویژگیها به کد TextView اضافه شده است.
app:layout_constraintBottom_toBottomOf="parent"
اگر به نحوه نامگذاری هر کدام دقت کنید کاربرد آن را متوجه خواهید شد.
Bottom to Bottom of parent یعنی پایینِ TextView به پایینِ parent متصل شود. و به همین ترتیب برای ۳ مورد دیگر. نتیجه این میشود که ویجت از بالا و پایین به یک اندازه و همچنین از چپ و راست هم به یک اندازه فاصله گرفته بنابراین در مرکز صفحه قرار میگیرد.
با توجه به اینکه در اینجا برای تعیین فاصله از واحدهای اندازه گیری استفاده نشده لذا یک رابط کاربری ساده و انعطاف پذیر داریم که در هر صفحه نمایشی اجرا شود اعم از کوچک و بزرگ یا افقی و عمودی، همواره این TextView در مرکز صفحه قرار خواهد گرفت.
اگر یکی از این خطوط حذف شود چه اتفاقی خواهد افتاد؟ میخواهم خط بالا را حذف کنم. برای اینکار هم میتوان در حالت کد، ویژگی layout_constraintTop_toTopOf را از تکست ویو حذف کرد هم اینکه در حالت دیزاین، خط بالا را انتخاب کرده و delete کنیم. همچنین اگر روی هریک از خطوط راست کلیک کنیم گزینههای مختلفی نمایش داده میشود که یکی از آنها Delete است:
مشاهده میکنید با حذف خط اتصال بالا، TextView از جهت افقی در مرکز قرار دارد اما در جهت عمودی به پایین صفحه چسبیده است. برای در مرکز قرار گرفتن ویجت کافی است دوباره ویژگی layout_constraintTop_toTopOf با مقدار parent را در ویرایشگر کد اضافه کرده و یا در محیط ویژوال به وسیله عمل Drag & Drop دایره یا گره بالای ویجت را گرفته و روی لبه بالای صفحه رها کنم:
در نهایت مجدد توانستم ویجت را نسبت به بالا و پایین در مرکز قرار دهم.
برای مشاهده جزئیات بیشتر روی گزینه Attributes نوار سمت راست محیط دیزاین کلیک میکنم. سپس روی صفحه پیش نمایش یا Component tree ویجت TextView را انتخاب میکنم تا ویژگیهای مرتبط با آن نمایش داده شود:
در قسمت Declared Attributes عینا مواردی که در کد TextView دیدیم لیست شده و میتوان هرکدام را تغییر داد.
در قسمت Layout امکانات بیشتری برای اعمال تغییرات وجود دارد. در چهار جهت آیکون مربعی شکل که نماد ویجت انتخاب شده یعنی TextView است، فیلدهای عددی دیده میشود که در حالت پیش فرض عدد صفر را نشان میدهند. این اعداد، فاصله یا margin را از جهتهایی که توسط خط اتصال به والد یا یک ویجت دیگر متصل شده تعیین میکنند.
در اینجا که ویجت ما در مرکز صفحه قرار گرفته تعیین فاصله اهمیتی ندارد اما در ادامه آموزش و هنگامی که بخواهیم یک ویجت را در کنار یک ویجت دیگر قرار دهیم از این ویژگی استفاده خواهیم کرد.
تعیین فاصله از چپ و پایین توسط Bias
در سمت چپ و پایین دو گزینه در کنار عدد مارجین قرار دارد که توسط آن و با حرکت دادن دایره روی خط، میزان فاصله از چهار جهت را میتوان تغییر داد. این قابلیت Bias نام دارد. دقت داشته باشید در اینجا خبری از واحدهای px و dp نیست بلکه بر اساس درصد تعیین میشود. به صورت پیش فرض هردو Bias روی ۵۰ قرار دارد یعنی مرکز صفحه.
اگر بخاطر داشته باشید در کد مربوط به TextView ویژگی با نام Bias وجود نداشت. این یعنی مقدار پیش فرض Bias برای یک ویجت همین ۵۰% یا مقدار ۰٫۵ است و صرفا در صورتی این ویژگی به ویجت اضافه خواهد شد که مقداری غیر از ۵۰ برای آن درنظر بگیریم.
برای تمرین، ویجت روی صفحه یا همین گزینه پایین که مربوط به جهت افقی هست را مقداری به سمت چپ بکشید:
ملاحظه میکنید عدد Horizontal Bias به ۲۵ تغییر کرد و ویجت هم در جهت افق به اندازه ۲۵ درصد به سمت چپ نزدیکتر شد. حالا اگر کد ویجت را دوباره بررسی کنید خط زیر به آن اضافه شده:
app:layout_constraintHorizontal_bias="0.25"
در محیط ویژوال عدد از ۰ تا ۱۰۰ و در کد از ۰ تا ۱ تعیین میشود. یعنی ۲۵ درصد برای Bias افقی (Horizontal) برابر است با مقدار ۰٫۲۵ برای ویژگی آن در کدها.
صفحه پیش نمایش را در حالت افقی (Landscape) قرار میدهم:
باز هم ویجت در فاصله ۲۵ درصدی از سمت چپ صفحه قرار گرفته و انعطاف پذیری ConstraintLayout را ثابت میکند.
تعیین عرض و ارتفاع Widget یا View ها
عرض و ارتفاع هر ویجتی که به layout اضافه میشود ابتدا wrap_content است؛ یعنی به اندازه محتوای درون خودش جا میگیرد. اما دو حالت دیگر هم قابل انجام است.
در تصویر بالا مشاهده میکنید با بردن نشانگر بر روی یکی از فاصلههای افقی عبارت Wrap Content نمایش داده میشود. یکبار روی یکی از آنها کلیک میکنم:
نماد فاصلههای افقی از دو فلش به یک خط ممتد تغییر پیدا کرد و عبارت Fixed را نمایش میدهد. همچنین در قسمت Declared Attributes مقدار width از wrap_content به ۷۶dp برای من تغییر داده شد یعنی اندروید استودیو یک مقدار پیش فرض در واحد dp را درنظر گرفت. حالا من میتوانم مقدار مدنظر خودم را بجای ۷۶ وارد کنم.
در مواقعی به این حالت نیاز داریم که بخواهیم برای یک ویجت عرض یا ارتفاع مشخص و ثابتی را درنظر بگیریم و نباید اندازه آن به صفحه نمایش یا حالت قرار گیری آن بستگی داشته باشد.
یک مرتبه دیگر روی نماد فاصله افقی کلیک میکنم:
اینبار نوع فاصله گذاری به Match Constraints تغییر پیدا کرد. این حالت همان match_parents در layout هایی مانند RelativeLayout است اما در ConstraintLayout برای اینکه یک ویجت تمام عرض یا ارتفاع در دسترس را اشغال کند بجای match_parent مقدار ۰dp باید داده شود که اندروید استودیو این تغییر را به صورت خودکار برای من انجام داد:
با انجام این تغییر، ویجت از دو طرف چپ و راست به محلی چسبید که خطوط اتصال برقرار است. در تصویر زیر هنوز هم خطوط اتصال افقی فعال هستند اما چون فاصلهای بین TextView و لبههای صفحه پیش نمایش وجود ندارد قابل مشاهده نیست. البته از گرههای تو پر میتوان فعال بودن این دو را تشخیص داد.
در صورتی که تسلط کافی بر هردو حالت کد و دیزاین داشته باشید در هنگام ساخت و ویرایش صفحات بخصوص layout های پیچیده، کنترل بیشتری بر روی لایهها و ویجتها خواهید داشت.
خب! حالا که تا حدودی با کلیت کار آشنا شدیم ادامه آموزش را در قالب چند مثال عملی طراحی صفحات با ConstraintLayout پیش میبرم تا درک بهتری از امکانات آن داشته باشید.
از مسیر New > Layout Resource file یک layout جدید با نام layout_two.xml به پروژه اضافه میکنم. هر قسمت را در یک فایل جداگانه توضیح میدهم تا همه کدها در سورس پروژه ضمیمه شده را در اختیار داشته باشید.
یک ویجت Button را از پالت ابزار کشیده و در مرکز صفحه پیش نمایش قرار میدهم:
اینجا ظاهرا مشکلی نیست و پس از رها کردن، دکمه در مرکز صفحه باقی میماند. حالا میخواهم پروژه را اجرا کنم تا خروجی کار را روی دیوایس اندرویدی هم ببینیم. در MainActivity.java فایل layout_two را جایگزین activity_main میکنم تا هنگام اجرای پروژه روی دیوایس نمایش داده شود.
MainActivity.java
package ir.android_studio.constraintlayout; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.layout_two); } }
پروژه را روی شبیه ساز Genymotion اجرا میکنم:
برخلاف آنچه در Preview اندروید استودیو دیدیم که دکمه در مرکز طولی و عرضی صفحه نمایش قرار گرفته بود، روی دیوایس اندرویدی دکمه در گوشه صفحه قرار گرفته است. به سورس layout دقت کنید:
layout_two.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" tools:layout_editor_absoluteX="156dp" tools:layout_editor_absoluteY="342dp" /> </androidx.constraintlayout.widget.ConstraintLayout>
دو ویژگی layout_editor_absoluteX و layout_editor_absoluteY فقط در صفحه پیش نمایش اندروید استودیو کاربرد دارند و تا زمانی که خطوط constraint برای ویو یا ویجت ساخته نشود موقعیت آن در صفحه تغییری نخواهد کرد. گرههای چپ و راست دکمه را به دو طرف صفحه متصل میکنم:
مشاهده میکنید دکمه در جهت افقی درست در مرکز صفحه قرار گرفته. ویژگیهای layout_editor_absolute تنها زمانی فعال میشود که خطوط اتصال در آن جهت وجود نداشته باشد. بنابراین با اضافه شدن دو خط چپ و راست، ویژگی layout_editor_absoluteX از دکمه حذف شد و فقط layout_editor_absoluteY باقی ماند:
<Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" tools:layout_editor_absoluteY="342dp" />
در حال حاضر نحوه نمایش وضعیت constraint ویجت دکمه به اینصورت است:
در جهت بالا و پایین نماد + وجود دارد که به وضوح نشان میدهد در این گرهها اتصالی انجام نشده است. البته اگر اینجا روی + کلیک کنیم علاوه بر ایجاد خط اتصال، یک فاصله (margin) به مقداری که قبلا در layout_editor_absoluteY تعریف شده نیز اضافه خواهد شد.
به عبارت دیگر layout_marginTop جایگزین ویژگی layout_editor_absoluteY میشود:
بنابراین بهتر است ایجاد خط اتصال به همان شیوه Drag & Drop روی صفحه پیش نمایش انجام شود یا در صورت ایجاد آن از طریق دکمه + لازم است مقدار margin صفر و یا به عدد دلخواه اصلاح شود.
در نوار بالای پیش نمایش چندین گزینه وجود دارد که دو مورد را در اینجا و مابقی را بعدا توضیح خواهم داد.
حذف یکباره تمامی Constraint ها
گزینه Clear All Constraints همانطور که از نامش پیداست تمامی اتصالاتی که درون layout بر روی ویجتها اعمال شده را به یکباره حذف میکند. این مورد مواقعی کاربرد دارد که تعدادی تغییرات در صفحه انجام دادهایم و لازم است همگی اصلاح شوند. با استفاده از این گزینه همه تغییرات قبلی حذف شده و لازم نیست یک به یک constraint ها را حذف کنیم.
همچنین کاربرد دیگر آن هنگامی است که یک layout که قبلا با استفاده از یک ViewGroup دیگر مانند LinearLayout طراحی شده را بخواهیم به ConstraintLayout تبدیل کنیم.
تبدیل ViewGroup های دیگر به ConstraintLayout
برای مثال قصد داریم رابط کاربری مربوط به آموزش دیتابیس در اندروید که قبلا با استفاده از RelativeLayout ساخته بودیم را به ConstraintLayout تبدیل کنیم. در قسمت Component Tree روی ViewGroup راست کلیک کرده و گزینه Convert RelativeLayout to ConstraintLayout را انتخاب میکنم:
پس از انجام عملیات تبدیل، اندروید استودیو به صورت خودکار اتصالات Constraint را بر اساس چینش قبلی ویجتها انجام میدهد اما خب عمدتا و بخصوص در لایههای پیچیده، آن چیزی که ما انتظارش را داریم اتفاق نمیافتد و لازم است خودمان نحوه چیدمان المانها را به صورت دستی انجام دهیم.
ایجاد خودکار Constraint ها
گزینه Infer Constraints عملی متضاد با Clear All Constraints را انجام میدهد. واژه infer به معنی “حدس زدن” است. یعنی در یک layout از جنس ConstraintLayout که یک یا چندین ویجت بدون خطوط اتصال و مابقی قابلیتهای آن اضافه شده، با کلیک روی این گزینه، اندروید استودیو به صورت حدسی تنظیمات و خطوط اتصال را برای آنها اعمال میکند اما همانطور که در قسمت قبل اشاره شد، این تنظیمات عموما رضایت بخش نبوده و در عمل کاربرد زیادی نخواهد داشت.
فعلا با ویجت دکمه کاری ندارم و آنرا از صفحه حذف میکنم.
یک گزینه دیگر با نام Default Margins در بالای صفحه Preview وجود دارد:
تعیین فاصله یا Margin پیش فرض
در طراحی یک layout برای ایجاد فاصله بین المانهای مختلف از ویژگی Margin استفاده میکنیم. معمولا فاصلهای که در یک layout برای المانهای مختلف استفاده میشود یکسان است تا چینش عناصر در رابط کاربری منظم و یکپارچه باشد.
مقدار Defalut Margin به طور پیش فرض روی عدد ۰ تنظیم شده. من این مقدار را روی ۱۶dp تنظیم میکنم و کار را ادامه میدهم.
ابتدا یک ImageView به صفحه اضافه میکنم:
در قسمت Attributes عرض این ویجت را ۰dp یا همان Match Constraint و ارتفاع را ۲۰۰dp تعیین میکنم. همچنین ویژگی scaleType را بر روی centerCrop تنظیم میکنم تا در هر اندازهای از صفحه نمایش، تصویر به طور کامل در محل ImageView قرار گرفته و فضای خالی در اطراف آن ایجاد نشود:
سپس گرههای سه جهت بالا و چپ و راست را به سه طرف والد یا به عبارتی لبههای صفحه نمایش متصل میکنم:
در تصویر بالا ملاحظه میکنید دو گره متصل شده یک فاصله ۱۶dp از لبه گرفتهاند. قبلا این عدد را در Defalut Margin تعریف کرده بودیم. همچنین بعد از اینکه گرههای بالا و سمت چپ را متصل کردم، به دلیل اینکه قبلا عرض تصویر به اندازه عرض صفحه پیش نمایش کشیده شده بود، گره سمت راست در داخل کادر قرار ندارد. اگر موس را بر روی خط چین سمت راست قرار داده و آنرا به سمت لبه راست صفحه بکشم خط اتصال برقرار میشود. یا اینکه در کادر Attributes در قسمت Constraint Widget روی نماد + سمت راست ویجت ImageView کلیک میکنم. اینجا فاصله ۱۶dp به طور خودکار اعمال نشد بنابراین به صورت دستی وارد میکنم. خروجی نهایی کار به اینصورت خواهد بود:
layout_two.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView android:id="@+id/imageView5" android:layout_width="0dp" android:layout_height="200dp" android:layout_marginStart="16dp" android:layout_marginLeft="16dp" android:layout_marginTop="16dp" android:layout_marginEnd="16dp" android:layout_marginRight="16dp" android:scaleType="centerCrop" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:srcCompat="@drawable/img_22" /> </androidx.constraintlayout.widget.ConstraintLayout>
تا اینجای کار ما یک تصویر به بالای صفحه اضافه کردیم که در هر اندازهای از صفحه نمایش، از سه جهت فاصله ۱۶dp خواهد داشت.
ذهنتان را محدود به کارهایی که من انجام میدهم نکنید. برای مثال میتوانستم اندازه کادر تصویر در صفحه پیش نمایش را کوچک کنم تا بتوانم هرسه گره را در داخل صفحه به لبهها متصل کرده و بعد عرض را match constraint تعیین کنم. یا اینکه میشد در محیط Code به سادگی ویژگیهای خط اتصال constraint و margin را برای ImageView تعیین کرد بدون آنکه نیازی به این جابجاییها در محیط Design داشته باشیم.
شاید در نحوه تنظیم چیدمان من ایرادی وجود داشته باشد و شما بتوانید آنرا بهتر و سادهتر اجرا کنید. البته شاید که نه؛ حتما!
در قدم بعد قصد دارم یک آیکون یا تصویر را به نحوی روی تصویر فعلی قرار دهم که مرکز آن، لبه پایینی این ImageView باشد. ابتدا یک ImageView دیگر را از پالت روی صفحه پیش نمایش کشیده و یک آیکون یا تصویر را به دلخواه انتخاب میکنم:
کد این ویجت به اینصورت است:
<ImageView android:id="@+id/imageView6" android:layout_width="40dp" android:layout_height="40dp" android:background="#DFCD2E" android:padding="5dp" app:srcCompat="@android:drawable/stat_sys_speakerphone" tools:layout_editor_absoluteX="47dp" tools:layout_editor_absoluteY="244dp" />
حالا گرههای بالا و پایین آیکون را به گره پایین ImageView قبلی متصل میکنم:
ملاحظه میکنید پس از انجام این کار، مرکز افقی تصویر دوم بر روی خط پایینی تصویر اول قرار گرفت. به همین سادگی!
در نهایت نود سمت چپ را هم به سمت چپ تصویر بزرگ متصل میکنم. با توجه به اینکه قبلا مقدار ۱۶dp را برای فاصله پیش فرض یا همان Default Margin تعیین کرده بودم، در اینجا نیز همین مقدار برای فاصله تعیین میشود:
حتما کد زیر و سایر کدهای هر قسمت از آموزش را به دقت بررسی کرده تا به خوبی درک کنید با انجام هر کار در محیط دیزاین، چه کدهایی به layout و ویجتها اضافه شده است.
layout_two.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/imageView5" android:layout_width="0dp" android:layout_height="200dp" android:layout_marginStart="16dp" android:layout_marginLeft="16dp" android:layout_marginTop="16dp" android:layout_marginEnd="16dp" android:layout_marginRight="16dp" android:scaleType="centerCrop" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:srcCompat="@drawable/img_22" /> <ImageView android:id="@+id/imageView6" android:layout_width="40dp" android:layout_height="40dp" android:layout_marginStart="16dp" android:layout_marginLeft="16dp" android:background="#DFCD2E" android:padding="5dp" app:layout_constraintBottom_toBottomOf="@+id/imageView5" app:layout_constraintStart_toStartOf="@+id/imageView5" app:layout_constraintTop_toBottomOf="@+id/imageView5" app:srcCompat="@android:drawable/stat_sys_speakerphone" /> </androidx.constraintlayout.widget.ConstraintLayout>
فرض کنید میخواهیم یک آیکون دیگر با همین وضعیت در سمت راست تصویر اضافه کنیم. تنها تفاوت در این است که در مرحله آخر بجای گره چپ، باید گره راست آیکون به گره راست تصویر بزرگ متصل شود.
یعنی اگر آیکونی که در اینجا قبل از اتصال گرهها در سمت چپ صفحه قرار داشت را بجای اتصال گره سمت چپ به قسمت چپ تصویر، گره راست آنرا به گره سمت راست تصویر یا لبه سمت راست صفحه متصل میکردم، در نهایت در سمت راست قرار میگرفت.
همتراز کردن ویجتهای متنی توسط Baseline
یکی دیگر از قابلیتهای بسیار کاربردی ConstraintLayout در ویجتهای متنی مانند EditText و Button ها استفاده میشود و Baseline نام دارد. توسط این ویژگی به سادگی میتوانیم دو ویجت را در راستای افقی در یک تراز قرار دهیم.
یک TextView و یک EditText به صفحه اضافه میکنم:
قابلیت Baseline بصورت پیش فرض روی ویجتها فعال نیست و با راست کلیک روی آن و انتخاب گزینه Show Baseline فعال میگردد:
پس از انجام این کار یک قسمت کپسولی شکل به وسط EditText اضافه شد:
با کشیدن آن به سمت وسط ویجت TextView کپسول Baseline این ویجت نیز ظاهر میشود. بنابراین خطی که از Baseline ویجت EditText کشیده شده را روی آن رها میکنم:
حالا این دو ویجت در یک تراز قرار گرفتهاند به طوری که متن درون EditText کاملا همراستای متن TextView دیده میشود. با تغییر موقعیت TextView ویجت EditText هم در همان جهت حرکت میکند و تراز باز هم برقرار باقی میماند.
منابع تکمیلی: Developer ، Developer ، Developer ، Developer ، Developer ، Medium
جهت مطالعه ادامه آموزش، فایل PDF را دانلود نمائید
توجه : سورس پروژه درون پوشه Exercises قرار دارد
با توجه به اینکه آموزشهای پایه با قیمت پایین در اختیار کاربر قرار گرفته و درآمد حاصل صرف تامین هزینههای وب سایت و تهیه آموزشهای آتی میشود، به اشتراک گذاری این فایل با دیگران خلاف اخلاق است.
تعداد صفحات : ۱۰۷
حجم : ۴ مگابایت
قیمت : ۴۶ هزار تومان
توجه: صرفا در صورتی از درگاه پشتیبان استفاده کنید که قادر به پرداخت از طریق سبد دانلود نباشید.
افزودن به سبد دانلود درگاه پشتیبان
سلام، وقت بخیر
من در قسمت Default margin یک عدد تعیین میکنم اما روی اشیا این مارجین اعمال نمیشه. توی کدهای layout هم نگاه کردم اعمال نمیشه. باید دستی اعمال کنم. چیکار کنم که به صورت default اجرا بشه رو همه اشیا؟؟
ممنون
مطمئنید طراحی رو درست انجام دادید؟ سورس پروژه ای که به همراه آموزش ضمیمه شده رو تست کنید ببینید بازم همین مشکل رو داره؟
سلام ،ببخشید یه سری attribute مثل size,textsize ،hint اینا رو من ندارم توی رابط کربریم چی کار کنم
ممکنه اشتباه استفاده میکنید ازشون. سورس کد رو با دقت بررسی کنید. ببینید با :android شروع میشه یا چیز دیگه ای
سلام
فایل آموزشی شما هم ویدئو دارد هم فایل pdf???
خیر فقط PDF هست
سلام من باتنی که میزارم میچسبه به سمت بالا سمت چپ جدا هم نمیشه؟!
هر موردی که لازم بوده و به ذهنم رسیده تو آموزش موجود هست. لطفا یکبار از ابتدا تا انتها و با دقت آموزش رو بررسی کنید ببینید ایراد کار کجاست
چجوری ازتون تشکر کنم ک اینقدر قشنگ توضیح دادید و مخصوصا کامل واقعا ممنون من چند سال ب دلایلی برنامه نویسی گذاشتم کنار، مونده بودم چجوری دوباره شروع کنم وقتی زبانم خیلی خوب نیست، ولی اینقدر قشنگ توضیح دادید امیدوار شدم دستتون درد نکنه
خدا رو شکر که مفید بوده براتون. موفق باشید
سلام خسته نباشید
ایا مشکلی پیش نمیاد ما از چند constraintlayout داخل هم استفاده کنیم ؟
چون بعضی جاها دیگه واقعا نیازه که یک سری ویو ها برای دسته بندی خوب داخل یک constraintlayout دیگه قرار بگیره
یا اگر قابلیت خاصی برای این اینکه بتونیم چندین ویو رو در یک دسته استفاده کنیم تا بتونیم سایر ویو هارو نسبت به اون دسته نمایش بدیم هست بگید استفاده کنیم ( قابلیت Group رو من چک کردم فقط برای visibility قابل استفاده هست )
هدف اصلی ConstraintLayout بی نیاز شدن از لایه های تو در تو یا nested هست و طبیعتا ایده خوبی نیست اینکار. من تست نکردم.
بعید میدونم اگه قابلیت ها رو درست بکار بگیرید نیازی به این کار باشه
باسلام و خسته نباشید چند بار برای خرید ConstraintLayout تلاش کردم ولی در صفحه دانلودهای من بدون استفاده درج شده لطفا بررسی و بفرمایید چکاری باید انجام دهم. از حسابم هم کم شده.
باتشکر اصغری
سلام. تراکنش ها رو بررسی کردم تراکنش داخل پنل ثبت نشده. این یعنی اگر هم مبلغ از حسابتون کسر شده مجدد از طریق بانک به حسابتون برگشت خورده. لطفا حسابتون رو بررسی کنید اگر برگشت نخورده از طریق صفحه “تماس با ما” اطلاع بدید پیگیری بشه.
ممنون
سلام مهندس/ تصویر به Design معرفی کردم کردم و وقتی خروجی میگیرم که روی شبیه ساز به نمایش در بیاد تصویر نصف هست کامل به نمایش درنمیاد.ممنون میشم مشکلم حل کنید/
چیزی نیست که من یا کس دیگه ای بتونه مشکلتون رو حل کنه. بگردید ببینید ایراد کارتون کجاست
سلام
من قبلاً پکیج کامل گرفتم ولی الان این آموزش جدید داخل پکیج وجود نداره. بخام دانلود کنم هم میگه باید هزینه بدم باز.
سلام. بزرگوار نحوه دریافت نسخه جدید دوره در توضیحات صفحه دوره آموزشی قید شده. باید وارد حساب کاربری بشید و در قسمت “دانلودهای من” مجدد دوره رو دانلود کنید. بدون پرداخت هزینه اضافی
منم دقیقا همین کارو کردم ولی تو بسته نیست. هنوز شما دوره ای که دانلود میکنم نیست. چندبار دانلود کردم ولی نیست
برای اینکه ببینید چه موارد جدیدی به دوره اضافه شده “لیست تغییرات دوره” که در انتهای صفحه معرفی دوره موجود هست رو باید بررسی کنید. یعنی این لینک:
https://android-studio.ir/android-course-update
اینجا نوشته شده آموزش ConstraintLayout در فصل ۵ اضافه شده یعنی شما باید در پوشه “۰۵ – UI Layout” این فایل رو پیدا کنید
ممنون