التخطيط والترتيب — أساسيات Flutter
التخطيط في Flutter
1. Column - ترتيب عمودي
Column(
mainAxisAlignment: MainAxisAlignment.center, // المحور الرئيسي (عمودي)
crossAxisAlignment: CrossAxisAlignment.start, // المحور الثانوي (أفقي)
mainAxisSize: MainAxisSize.min, // الحجم
children: [
Text('عنصر 1'),
SizedBox(height: 16), // مسافة
Text('عنصر 2'),
Text('عنصر 3'),
],
)
// MainAxisAlignment options:
// - start: البداية
// - end: النهاية
// - center: الوسط
// - spaceBetween: توزيع متساوي
// - spaceAround: مسافات حول
// - spaceEvenly: مسافات متساوية
2. Row - ترتيب أفقي
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(Icons.star, color: Colors.yellow),
Text('4.5'),
Text('(100 تقييم)'),
],
)
3. Stack - تراكب
Stack(
alignment: Alignment.center,
children: [
// الطبقة السفلى
Container(
width: 200,
height: 200,
color: Colors.blue,
),
// الطبقة العليا
Container(
width: 100,
height: 100,
color: Colors.red,
),
// موقع محدد
Positioned(
top: 10,
right: 10,
child: Icon(Icons.star, color: Colors.yellow),
),
],
)
4. Expanded و Flexible
Row(
children: [
// يأخذ المساحة المتبقية
Expanded(
flex: 2, // نسبة 2
child: Container(color: Colors.red, height: 100),
),
Expanded(
flex: 1, // نسبة 1
child: Container(color: Colors.blue, height: 100),
),
],
)
// Flexible - مرن بدون إجبار
Row(
children: [
Flexible(
child: Text('نص طويل جداً قد يتم قطعه...'),
),
Text('ثابت'),
],
)
5. Wrap - التفاف تلقائي
Wrap(
spacing: 8, // مسافة أفقية
runSpacing: 8, // مسافة عمودية
children: [
Chip(label: Text('Flutter')),
Chip(label: Text('Dart')),
Chip(label: Text('Mobile')),
Chip(label: Text('iOS')),
Chip(label: Text('Android')),
],
)
6. GridView
// شبكة ثابتة الأعمدة
GridView.count(
crossAxisCount: 2,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
padding: EdgeInsets.all(16),
children: List.generate(10, (index) {
return Container(
color: Colors.blue[100 * (index % 9 + 1)],
child: Center(child: Text('$index')),
);
}),
)
// شبكة ديناميكية
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
childAspectRatio: 1.0, // نسبة العرض للارتفاع
),
itemCount: items.length,
itemBuilder: (context, index) {
return ProductCard(product: items[index]);
},
)
7. SingleChildScrollView
SingleChildScrollView(
padding: EdgeInsets.all(16),
child: Column(
children: [
// محتوى طويل
],
),
)
8. مثال تطبيقي: بطاقة منتج
class ProductCard extends StatelessWidget {
final String title;
final String image;
final double price;
final double rating;
const ProductCard({
required this.title,
required this.image,
required this.price,
required this.rating,
});
@override
Widget build(BuildContext context) {
return Card(
clipBehavior: Clip.antiAlias,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// الصورة
Expanded(
child: Image.network(
image,
width: double.infinity,
fit: BoxFit.cover,
),
),
// المحتوى
Padding(
padding: EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
SizedBox(height: 4),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'$price د.ع',
style: TextStyle(
color: Colors.green,
fontWeight: FontWeight.bold,
),
),
Row(
children: [
Icon(Icons.star, size: 16, color: Colors.amber),
Text(' $rating'),
],
),
],
),
],
),
),
],
),
);
}
}
اختبر فهمك