Container والتزيين
ودجة Container
ودجة Container هي واحدة من أكثر الودجات تنوعاً واستخداماً في Flutter. تجمع بين إمكانيات الرسم والتحديد والتحجيم الشائعة في ودجة واحدة مريحة. يمكن لـ Container تطبيق الحشو الداخلي والهوامش والحدود وألوان الخلفية والتدرجات والظلال والتحويلات على العنصر الابن.
فكر في Container كـ div في HTML/CSS -- هو الصندوق متعدد الأغراض الذي تستخدمه لتنسيق المحتوى وتحديد موقعه.
Container أساسي
Container(
width: 200,
height: 100,
color: Colors.blue,
child: const Center(
child: Text(
'مرحباً Container',
style: TextStyle(color: Colors.white),
),
),
)
خصائص Container الرئيسية:
width/height-- أبعاد ثابتة للحاوية.color-- لون الخلفية (لا يمكن استخدامه معdecoration).padding-- المسافة داخل الحاوية، بين الحدود والعنصر الابن.margin-- المسافة خارج الحاوية، بين الحاوية والعنصر الأب.alignment-- كيفية محاذاة العنصر الابن داخل الحاوية.constraints-- قيود حجم إضافية (أدنى/أقصى عرض وارتفاع).decoration--BoxDecorationللتنسيق المتقدم (يحل محلcolor).transform-- تحويل مصفوفة يُطبق على الحاوية.
color و decoration على نفس Container. إذا كنت تحتاج لون خلفية مع حدود أو تزيين آخر، اضبط اللون داخل BoxDecoration بدلاً من ذلك.الحشو الداخلي مقابل الهامش
فهم الفرق بين الحشو الداخلي والهامش أمر حاسم للتخطيط:
- الحشو الداخلي (Padding) -- المسافة داخل الحاوية، بين حدود الحاوية والعنصر الابن.
- الهامش (Margin) -- المسافة خارج الحاوية، بين الحاوية والودجات المحيطة.
الحشو الداخلي مقابل الهامش
Container(
// مسافة خارجية (تدفع بعيداً عن الأب/الأشقاء)
margin: const EdgeInsets.all(20),
// مسافة داخلية (تدفع الابن للداخل)
padding: const EdgeInsets.all(16),
color: Colors.blue[100],
child: const Text('لدي هامش وحشو داخلي'),
)
// خيارات EdgeInsets:
// EdgeInsets.all(8) - متساوٍ على جميع الجوانب
// EdgeInsets.symmetric(horizontal: 16, vertical: 8)
// EdgeInsets.only(left: 10, top: 20)
// EdgeInsets.fromLTRB(10, 20, 10, 20) - يسار، أعلى، يمين، أسفل
التعمق في BoxDecoration
BoxDecoration هي القوة المحركة لتنسيق Container. توفر تحكماً دقيقاً في المظهر البصري للحاوية بما في ذلك الألوان والتدرجات والحدود والزوايا المستديرة والظلال وصور الخلفية.
نظرة عامة على خصائص BoxDecoration
Container(
width: 200,
height: 200,
decoration: BoxDecoration(
// لون الخلفية
color: Colors.white,
// زوايا مستديرة
borderRadius: BorderRadius.circular(16),
// حدود
border: Border.all(
color: Colors.blue,
width: 2,
),
// ظل
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.2),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: const Center(
child: Text('صندوق مزخرف'),
),
)
خلفيات متدرجة
يدعم BoxDecoration ثلاثة أنواع من التدرجات: LinearGradient و RadialGradient و SweepGradient.
أنواع التدرجات
// تدرج خطي
Container(
width: 300,
height: 150,
decoration: BoxDecoration(
gradient: const LinearGradient(
colors: [Colors.purple, Colors.blue, Colors.cyan],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(12),
),
)
// تدرج شعاعي
Container(
width: 200,
height: 200,
decoration: BoxDecoration(
gradient: RadialGradient(
colors: [Colors.yellow, Colors.orange, Colors.red],
radius: 0.8,
),
shape: BoxShape.circle,
),
)
// تدرج دائري
Container(
width: 200,
height: 200,
decoration: const BoxDecoration(
gradient: SweepGradient(
colors: [
Colors.red,
Colors.orange,
Colors.yellow,
Colors.green,
Colors.blue,
Colors.purple,
Colors.red,
],
),
shape: BoxShape.circle,
),
)
أنماط الحدود
يمكنك تطبيق حدود موحدة أو حدود مختلفة على كل جانب:
أمثلة الحدود
// حدود موحدة
Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.blue, width: 2),
borderRadius: BorderRadius.circular(8),
),
)
// حدود مختلفة لكل جانب
Container(
decoration: const BoxDecoration(
border: Border(
top: BorderSide(color: Colors.red, width: 3),
bottom: BorderSide(color: Colors.blue, width: 3),
left: BorderSide(color: Colors.green, width: 1),
right: BorderSide(color: Colors.green, width: 1),
),
),
)
// حد سفلي فقط (مثل خط تحتي)
Container(
decoration: const BoxDecoration(
border: Border(
bottom: BorderSide(color: Colors.grey, width: 1),
),
),
)
Border())، لا يمكنك استخدام borderRadius. الزوايا المستديرة تعمل فقط مع الحدود الموحدة المنشأة بـ Border.all().ظلال الصندوق
خاصية boxShadow تقبل قائمة من كائنات BoxShadow، مما يسمح بظلال متعددة لتأثيرات معقدة:
أمثلة الظلال
// ظل خفيف واحد
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 8,
offset: const Offset(0, 2),
),
],
),
)
// ظلال متعددة للعمق
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 20,
offset: const Offset(0, 10),
),
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 6,
offset: const Offset(0, 3),
),
],
),
)
الشكل: دائرة مقابل مستطيل
خاصية shape يمكن أن تكون BoxShape.rectangle (الافتراضي) أو BoxShape.circle:
حاوية دائرية
// حاوية بنمط الصورة الرمزية الدائرية
Container(
width: 100,
height: 100,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.blue,
border: Border.all(color: Colors.white, width: 3),
boxShadow: [
BoxShadow(
color: Colors.blue.withOpacity(0.3),
blurRadius: 12,
offset: const Offset(0, 4),
),
],
),
child: const Center(
child: Text(
'أب',
style: TextStyle(
color: Colors.white,
fontSize: 32,
fontWeight: FontWeight.bold,
),
),
),
)
BoxShape.circle، لا تضبط borderRadius -- سيرمي خطأ. شكل الدائرة يقص الحاوية تلقائياً إلى دائرة. تأكد أيضاً أن Container لديه width و height متساويان للحصول على دائرة مثالية.صورة الخلفية
خاصية image في BoxDecoration تتيح لك تعيين صورة خلفية:
حاوية بصورة خلفية
Container(
width: 300,
height: 200,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
image: const DecorationImage(
image: NetworkImage('https://picsum.photos/300/200'),
fit: BoxFit.cover,
),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.3),
blurRadius: 10,
offset: const Offset(0, 5),
),
],
),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
gradient: LinearGradient(
colors: [
Colors.black.withOpacity(0.6),
Colors.transparent,
],
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
),
),
padding: const EdgeInsets.all(16),
alignment: Alignment.bottomLeft,
child: const Text(
'صورة مع طبقة تراكب',
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
),
)
قيود الحاوية
خاصية constraints تقبل كائن BoxConstraints الذي يحدد الأبعاد الدنيا والقصوى:
استخدام القيود
Container(
constraints: const BoxConstraints(
minWidth: 100,
maxWidth: 300,
minHeight: 50,
maxHeight: 200,
),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.teal[50],
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.teal),
),
child: const Text(
'هذه الحاوية تتكيف مع حجمها بناءً على المحتوى، '
'لكنها تبقى ضمن القيود المحددة.',
),
)
تحويل الحاوية
خاصية transform تطبق تحويل Matrix4 على الحاوية. هذا مفيد للدورانات والتكبير والإزاحات.
أمثلة التحويل
// الدوران
Container(
width: 100,
height: 100,
transform: Matrix4.rotationZ(0.1), // بالراديان
decoration: BoxDecoration(
color: Colors.orange,
borderRadius: BorderRadius.circular(12),
),
child: const Center(child: Text('مائل')),
)
// التكبير
Container(
width: 100,
height: 100,
transform: Matrix4.diagonal3Values(1.2, 1.2, 1),
transformAlignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.purple,
borderRadius: BorderRadius.circular(12),
),
child: const Center(
child: Text('مُكبَّر', style: TextStyle(color: Colors.white)),
),
)
transformAlignment (متاح في Flutter 3.x) لتعيين نقطة أصل التحويل. افتراضياً، تُطبق التحويلات من الزاوية العلوية اليسرى، مما قد ينتج نتائج غير متوقعة للدورانات.ودجة DecoratedBox
إذا كنت تحتاج فقط التزيين بدون تحجيم أو حشو، استخدم DecoratedBox مباشرةً بدلاً من Container. هي ودجة أخف تطبق فقط BoxDecoration:
DecoratedBox مقابل Container
// DecoratedBox - خفيف، تزيين فقط
const DecoratedBox(
decoration: BoxDecoration(
color: Colors.amber,
borderRadius: BorderRadius.all(Radius.circular(8)),
),
child: Padding(
padding: EdgeInsets.all(16),
child: Text('باستخدام DecoratedBox'),
),
)
// Container يفعل نفس الشيء لكن بحمل أكبر
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.amber,
borderRadius: BorderRadius.circular(8),
),
child: const Text('باستخدام Container'),
)
أمثلة عملية
بطاقة منسقة
بطاقة منسقة مخصصة
Container(
margin: const EdgeInsets.all(16),
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.08),
blurRadius: 16,
offset: const Offset(0, 4),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
Container(
width: 48,
height: 48,
decoration: BoxDecoration(
color: Colors.blue[50],
borderRadius: BorderRadius.circular(12),
),
child: Icon(Icons.star, color: Colors.blue[600]),
),
const SizedBox(width: 12),
const Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'الخطة المميزة',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
Text(
'\$9.99/شهرياً',
style: TextStyle(color: Colors.grey),
),
],
),
],
),
const SizedBox(height: 16),
const Text(
'افتح جميع الميزات واحصل على وصول غير محدود.',
),
],
),
)
صورة رمزية دائرية
صورة رمزية دائرية مخصصة
Container(
width: 120,
height: 120,
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: const LinearGradient(
colors: [Colors.purple, Colors.deepOrange],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
border: Border.all(color: Colors.white, width: 4),
boxShadow: [
BoxShadow(
color: Colors.purple.withOpacity(0.4),
blurRadius: 20,
offset: const Offset(0, 8),
),
],
),
child: const Center(
child: Text(
'إس',
style: TextStyle(
color: Colors.white,
fontSize: 40,
fontWeight: FontWeight.bold,
),
),
),
)
تمرين عملي
أنشئ بطاقة ملف شخصي باستخدام Container و BoxDecoration تتضمن: (1) خلفية متدرجة من أعلى اليسار إلى أسفل اليمين. (2) زوايا مستديرة بنصف قطر 20. (3) ظل خفيف بنصف قطر ضبابي 15 وإزاحة عمودية 6. (4) بالداخل: حاوية صورة رمزية دائرية في الأعلى، ونص الاسم، ونص الوصف. (5) يجب أن يكون للصورة الرمزية حد أبيض وتدرج دائري. التحدي: أضف transform لإمالة البطاقة قليلاً واستخدم DecorationImage لنمط خلفية.