مقدمة :
إن الغرض الأكبر من التطبيقات هو عرض المعلومات على شكل منظم يسهل قراءته والتعامل معه , لهذا كانت القوائم في فلاتر ListView التي ستقوم بعرض قائمة من العناصر على المحور الشاقولي أو الأفقي مع مع خصائص متكاملة للتحكم الكامل بها .
في هذا المقال سنعرض أبرز استخدامات القوائم واهم خصائصه التي ستتعامل معها بشكل دوري أثناء إنجازك لواجهة التطبيق .
تضمين القائمة ListView :
يتم تضمين قائمة العناصر ضمن عنصر آخر يمكن تحديد قياسه , مثل Container أو SizedBox , أو ضمن عنصر سيتحدد قياسه بناءً على مقاس الشاشة المتبقي مثل Flexble أو Expanded , و تحمل القائمة مصفوفة من العناصر داخلها List<Widget>
سيقوم الكود التالي بعرض قائمة تحوي ثلاث حاويات Container لكل منها خصائصها ولونها
ListView(
padding: const EdgeInsets.all(8),
children: [
Container(
height: 50,
color: Colors.red,
child: const Center(child: Text('Item 1')),
),
Container(
height: 50,
color: Colors.blue,
child: const Center(child: Text('Item 1')),
),
Container(
height: 50,
color: Colors.orange,
child: const Center(child: Text('Item 1')),
),
],
)
خصائص القوائم :
• children : مصفوفة من العناصر List<Widget> المحتواة داخل القائمة .
• scrollDirection : إتجاه القائمة و يأخذ قيمة Axis وهو من نوع Enum ويحمل نوعين (Axis.vertical,Axis.horizental ) .
• reverse : عكس القائمة , حيث ستعرض عناصر القائمة بشكل معكوس ويأخذ قيمة bool والقيمة الافتراضية له false .
• controller : يأخذ instance من كلاس ScrollController ويستخدم للتحكم بالقائمة حيث يمكنك من خلاله قراءة أو تعيين حالة السحبscroll بشكل برمجي .
• physics : يتم من خلالها تعيين ماذا سيحدث عند وصول المستخدم لنهاية القائمة أو عند توقفه عن السحب و يأخذ قيمة من كلاس ScrollPhysics .
• shrinkWrap : من نوع bool و يعني أن قياس القائمة سيحتاج إلى إعادة حساب كلما تغير السحب , وتستخدم عادة إذا كان قياس العناصر المحتواة ضمن القائمة غير محدد وقياس العنصر الحاوي للقائمة غير محدد ( كاستخدام القائمة ضمن Flexble أو Expanded ) والقيمة الافتراضية له هي false .
• padding : يستخدم لوضع حدود داخلية لبدء ظهور العناصر ويأخذ قيمة EdgeInsets كمثال EdgeInsets.all(5)
سطر القائمة ListTile :
هي عناصر جاهزة على شكل سطور , تحوي خصائصاً بسيطة يمكن وضعها داخل القائمة ( كأبناء ) أو تضمينها في أي مكان في التطبيق , لها ارتفاع ثابت و تحتوي نصوصاً وعناصر بادئة leading أو لاحقة trailing .
يقسم سطر العنصر إلى ثلاثة أقسام يمكن استعمالها جميعها أو بعضها وهي :
leading : عنصر البادئة ( أول السطر ) ويظهر في الصورة التالية كشعار flutter .
النص : عبارة عن سطرين من النصوص الأول هو العنوان title و الثاني هو النص اللاحق subtitle .
trailing : عنصر اللاحقة ( في آخر السطر ) ويظهر في الصورة التالية كأيقونة النقاط الثلاث .
أبرز خصائص عنصر سطر القائمة :
ListTile(
title: const Text('Title will shown here'),
subtitle: const Text('subTitle will shown here'),
leading : Icon(Icons.heart),
trailing : Icon(Icons.more_vert),
dense : true,
tileColor: Colors.blue,
onTap: () {
Navigator.pop(context);
},
),
• leading : يأخذ قيمة Widget حيث يمكنك استعمال أي عنصر ( صورة - أيقونة - نص ) .
• title : العنوان ويأخذ قيمة Widget و غالباً ما يستعمل فيه النص Text ويظهر بصورة افتراضية بلون غامق .
• subtitle : العنوان الفرعي ويأخذ قيمة Widget و غالباً ما يستعمل فيه النص Text ويظهر بصورة افتراضية بلون فاتح.
• trailing : يأخذ قيمة Widget و يمكنك استعمال أي عنصر وغالباً ما تستخدم الأيقونات فيه .
• isThreeLine : يأخذ قيمة bool ويحدد فيما إذا كان السطر سيعرض ثلاث سطور من النصوص ( سطرين في العنوان الفرعي ) .
• enabled : يأخذ قيمة bool ويحدد فيما إذا كان العنصر قابلاً للضغط عليه أم لا ( نشط أو غير نشط ) .
• minVerticalPadding : يأخذ قيمة double ويحدد التباعد الداخي على المحور الرأسي لعنصر القائمة .
• contentPadding : يأخذ قيمة كلاس EdgeInsetsGeometry ويحدد التباعد الداخلي للسطر حسب القيمة المعينة مثل EdgeInsets.all(5)
• mouseCursor : شكل مؤشر الماوس ( في حال تشغيل التطبيق للويب ) يأخذ قيمة كلاس MouseCursor .
• style : ستايل السطر ويأخذ قيمة ListTileStyle و هو من نوع Enum ويحمل خيارين : list و تعني أنه عنصر قائمة عادية أو drawer وتعني أنه عنصر قائمة جانبية .
• textColor : لون النص ويأخذ قيمة لون Color حيث يمكنك التحكم بلون النص من خصائص السطر دون الحاجة للتحكم به ضمن خصائص النص .
• tileColor : لون خلفية السطر ويأخذ قيمة لون Color .
• dense : يأخذ قيمة bool ويحدد فيما إذا كان السطر جزء من قائمة طويلة ( سيتقلص ارتفاعه إذا كانت قيمة dense هي true ) .
• onTap : يأخذ قيمة Function ويحدد ما سيتم تنفيذه عند الضغط على السطر
ملاحظة هامة :
يمكنك التحكم في خصائص السطور بشكل عام من خلال تحديد خصائصها عبر الثيم العامة للتطبيق ThemeData داخل خصائص MaterialApp , حيث لن تضطر لتعيين خصائص كل واحدة على حدا .
MaterialApp(
theme: ThemeData(
listTileTheme: const ListTileThemeData(
textColor: Colors.white,
)),
home: Scaffold(
appBar: AppBar(title: const Text('ListTile Samples')),
body: const LisTileExample(),
),
);
هل من داع لاستخدام ListTile , حيث يمكن بسهولة إنشاء عنصر شبيه من Row , Column ؟
الإجابة ببساطة أن هذا العنصر وجد لكي يسهل عليك إنشاء سطر قائمة و تم تخصيص الكثير من الخصائص له للتحكم بشكله و ألوانه ,
كما ان أغلب عناصره لها قيم افتراضية ( مقاسات ) تم وضعها استناداً لقواعد تصميم الواجهات , أنت بغنىً عن إعادة تصميمها وتشكيلها , لكن إذا كنت تحتاج لعنصر قائمة بخصائص محدودة يمكنك إنشاؤه بنفسك وتوفير مساحة من معالجة كافة خصائص سطر القائمة ListTile .
القائمة آلية البناء ListViewBuilder :
لنفرض أنك تريد عرض قائمة طويلة من المعلومات , قد تكون ضمن مصفوفة أو قائمة متغيرة من API خارجي , هل ستقوم بكتابة كود لكل عنصر كعنصر قائمة ؟
الحل هنا هو استخدام القائمة آلية البناء حيث يمكن من خلالها تحديد عدد العناصر المتوقع , وكيف سيتم بناء هذه العناصر وفق ترتيبها ضمن قائمة المعلومات .
في المثال التالي , قائمة معلومات عن أسماء الحيوانات ونود عرضها ضمن قائمة عناصر من نوع Text :
final List animals = ["dog", "cat", "Cow", "Duck", "Horse", "Rabbit", "Hen"];
بكل سهولة سوف نستخدم عنصر ListView.builder الذي سنعطيه عدد العناصر والذي هو animals.length وسيتم الدوران على هذه القائمة مثل حلقة for في لغات البرمجة من خلال خاصية itemBuilder التي تأخذ 2 بارمتر هما BuildContext وهو يدل على مكان العنصر ضمن شجرة عناصر واجهة المستخدم و الثاني هو من نوع int وهو الرقم الحالي عند الدوران على عناصر القائمة ويبدأ من صفر "dog"وينتهي بموقع آخر عنصر ضمن عناصر قائمة الحيوانات السابقة 6 ويشير إلى "Hen"
ListView.builder(
padding: const EdgeInsets.all(8),
itemCount: animals.length,
itemBuilder: (BuildContext context, int index) {
return Container(
height: 50,
child: Center(child: Text(Animals [index])),
);
}
)
أما عن خصائص العنصر فهو يحوي نفس خصائص القائمة ListView مع الخاصيتين (itemCount,itemBuilder)
المراجع :
ListView class - widgets library - Dart API (flutter.dev)
ListTile class - material library - Dart API (flutter.dev)
ListTileStyle enum - material library - Dart API (flutter.dev)