Flutter / Dart والعناصر والملكية المحلية / الدرس 3
القيود والتخطيط المتجاوب
فسّر تجاوز المحتوى بتتبّع القيود، ثم اختر حدود تخطيط تصمد أمام النص الطويل أو المكبّر.
في هذه الصفحة
أهداف الدرس
- تتبّع قيد الأب أولا
- افهم توزيع المساحة المرنة
- قيّد نص الصف عن قصد
تتبّع قيد الأب أولا
يتلقى صندوق Flutter من أبيه الحدين الأدنى والأقصى للعرض والارتفاع. يختار حجما ضمن تلك الحدود، ثم يحدد الأب موضعه. لذلك يمثل العرض المطلوب تفضيلا تحكمه القيود، لا أمرا مطلقا. ابدأ تشخيص التجاوز بتسمية المحور المتضرر وتتبع أقرب حد نهائي. قد يخفي الحشو العشوائي أو Center أو الأبعاد الثابتة صورة واحدة مع إبقاء التناقض الأصلي. ارسم سلسلة الأب والابن المعنية وسجّل العنصر المتوقع أن يستهلك المساحة الباقية قبل تغيير التخطيط.
افهم توزيع المساحة المرنة
يوزع Row وColumn الأبناء على محور رئيسي مع تطبيق قيود المحور المتقاطع. وقد يطلب الابن غير المرن مساحة أكبر مما هو متاح على المحور الرئيسي. يمنح Expanded ابنه حصة من المساحة المتبقية المحدودة، بينما قد يسمح Flexible بملاءمة أكثر مرونة. تعالج هذه الأدوات عقودا مختلفة؛ فافحص السلوك المطلوب بدلا من إضافة Expanded لكل ابن. يحتاج النص الملتف بجوار أيقونة إلى عرض محدود. وتحتاج قائمة التمرير الرأسي داخل Column إلى ارتفاع محدود أو تركيب تمرير مختلف مقصود.
قيّد نص الصف عن قصد
يحافظ المقتطف الأول على دور الأيقونة، ويخصص Expanded العرض المتبقي في الصف للنص. يعبّر maxLines وعلامة الحذف عن اختيار للمنتج: إظهار سطرين على الأكثر مع بيان الاختصار. وليسا علاجين إلزاميين للتجاوز. إذا كان الوصف الكامل ضروريا، فاسمح بالالتفاف والنمو الرأسي، أو وفّر عرض تفاصيل ميسّرا. راجع التخطيط بنص مترجم ونافذة ضيقة وحجم نص أكبر. التصميم الذي ينجح فقط مع عنوانه الأول القصير لم يحقق عقد قيود متينا.
Widget placeRow() => const Row(children: [
Icon(Icons.place),
SizedBox(width: 8),
Expanded(child: Text('Riverside learning center and reading room',
maxLines: 2, overflow: TextOverflow.ellipsis)),
]);
The label occupies the remaining finite row width and uses at most two lines.
يجب استعمال Expanded داخل أب مرن متوافق. ويفترض المثال أن Row نفسه يتلقى عرضا محدودا.
حدّد منطقة التمرير
يمنح المقتطف الثاني العنوان ارتفاعه الطبيعي ويخصص الارتفاع المتبقي لقائمة كسولة البناء. يناسب ذلك حين يتلقى Column ارتفاعا محدودا، كما في جسم Scaffold. ولا يناسب إحاطة Column كله بتمرير رأسي مع إبقاء Expanded، لأن حد المحور الرئيسي يصبح غير محدود. قرّر هل للصفحة سطح تمرير مستمر واحد أم عنوان ثابت ومحتوى قابل للتمرير. وقد تعبّر slivers عن بنية الصفحة المستمرة المعقدة أوضح من تداخل أبناء متعددي التمرير.
Widget readingList() => Column(children: [
const Padding(padding: EdgeInsets.all(16), child: Text('Reading list')),
Expanded(child: ListView.builder(
itemCount: 40,
itemBuilder: (context, index) => ListTile(title: Text('Chapter ${index + 1}')),
)),
]);
A header stays above a scrolling list of Chapter 1 through Chapter 40.
يسمح ارتفاع الأب المحدود لـ Expanded بتخصيص مساحة عرض. وتُطلب العناصر عند الحاجة بدلا من تخطيطها كلها داخل Column.
استجب للمساحة المتاحة لا لاسم الجهاز
يكشف LayoutBuilder القيود في موضع معين، ويفيد عندما تحتاج بطاقة أو لوحة إلى تغيير ترتيبها بحسب عرضها المتاح. أما MediaQuery فيصف معلومات أوسع عن البيئة، وقد لا تمثل عرض مكوّن متداخل. اختر نقاط التحول بناء على حاجة المحتوى، مثل عدم اتساع عمودين بعرض مقروء. قد يكسر هاتف أفقي أو نافذة سطح مكتب ضيقة الافتراضات المبنية على أسماء المنصات فقط. وحافظ على اتساق التنقل وترتيب القراءة واستمرار التركيز عند تغير الترتيب.
تحقّق من الحالات القصوى للمحتوى
يشمل فحص التخطيط المفيد بيانات فارغة وصفا واحدا وصفوفا كثيرة ومعرّفات طويلة غير قابلة للكسر وتسميات من اليمين إلى اليسار وظهور لوحة المفاتيح ونصا كبيرا. تختبر هذه الحالات قيودا مختلفة. لا تعطّل تكبير النص لمجرد حفظ نموذج بصري. فضّل تخطيطا ينمو أو يلتف أو يتمرر أو يغير تركيبه مع حفظ المعنى. إذا ذكر التحقق ارتفاعا غير محدود أو RenderFlex متجاوزا، فاحتفظ بأول استثناء ذي صلة وبشجرة مصغرة. قد تكون أخطاء الرسم اللاحقة مجرد نتائج للخلل الأول.
الأخطاء الشائعة وإصلاحها
يتجاوز Row حدوده بجوار نص طويل
- لماذا يحدث؟
- لم يتلق النص عقدا مناسبا للعرض المتبقي.
- كيف تصلحه؟
- استخدم ابنا مرنا مناسبا وحدّد الالتفاف أو الاختصار.
- كيف تتجنب تكراره؟
- اختبر الترجمات الطويلة عند عرض ضيق.
يتلقى منفذ عرض رأسي ارتفاعا غير محدود
- لماذا يحدث؟
- وُضع عنصر تمرير داخل أب رأسي لا يحد ارتفاعه.
- كيف تصلحه؟
- حدّد ارتفاع منفذ العرض أو أعد تصميم الصفحة كسطح تمرير واحد.
- كيف تتجنب تكراره؟
- ارسم ملكية التمرير والحدود النهائية.
يفشل Expanded داخل تمرير رأسي
- لماذا يحدث؟
- لا يوجد ارتفاع متبق محدود يمكن توزيعه.
- كيف تصلحه؟
- أزل عقد المرونة المتناقض واختر تركيب تمرير مناسبا.
- كيف تتجنب تكراره؟
- راجع حدود المحور الرئيسي قبل إضافة المرونة.
اختبر فهمك
1. تحتاج الصفحة إلى حقل بحث ثابت وقائمة نتائج طويلة. أين يكون التمرير؟
اعرض الحل المشروح
استخدم جسما محدودا للصفحة يحوي Column وفيه حقل البحث وقائمة داخل Expanded. تملك القائمة تمرير النتائج. وإذا تقرر لاحقا أن يختفي البحث مع التمرير، فأعد التفكير في الصفحة كسطح تمرير واحد بدلا من تداخل تمريرات متناقضة.
2. كيف تقرر بطاقة ذات عمودين متى تتحول إلى ترتيب رأسي؟
اعرض الحل المشروح
قِس القيود المتاحة للمكوّن والحد الأدنى المفيد لعرض المحتوى، بما فيه الفراغ والحشو. اختر نقطة تحول من هذا الاحتياج ثم اختبر النص الطويل والمكبّر. لا تصف فئة الجهاز وحدها المساحة الفعلية المخصصة للمكوّن.
أهم ما تعلمته
- تتبّع قيد الأب أولا
- تحقّق من الحالات القصوى للمحتوى