اجمع الألوان والطباعة مركزيًا في ThemeData، وولِّد لوحة ألوان Material 3 باستخدام ColorScheme.fromSeed، وقدّم وضعًا داكنًا دون عناء.
افتح هذا الدرس في Kodokonإن التوقّف عن تنسيق كل ويدجت على حدة مرحلة احترافية: إذ يجمع ThemeData الألوان والطباعة والأشكال للتطبيق بأكمله في مكان مركزي. ومع Material 3 (المُفعَّل افتراضيًا منذ Flutter 3.16)، ينطلق كل شيء من ColorScheme: يشتقّ ColorScheme.fromSeed لوحة ألوان كاملة ومتناسقة وسهلة الوصول من لون بذرة (seed) واحد.
import 'package:flutter/material.dart';
void main() {
runApp(const ShopApp());
}
class ShopApp extends StatelessWidget {
const ShopApp({super.key});
@override
Widget build(BuildContext context) {
const seed = Colors.teal;
return MaterialApp(
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: seed,
),
),
darkTheme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: seed,
brightness: Brightness.dark,
),
),
themeMode: ThemeMode.system,
home: Scaffold(
appBar: AppBar(title: const Text('Shop')),
body: const Center(child: Text('Welcome')),
),
);
}
}داخل ويدجاتك، لا تُعِد اختراع أيّ شيء: اقرأ السِّمة المحيطة باستخدام Theme.of(context). يكشف colorScheme عن أدوار دلالية (primary وonPrimary وprimaryContainer وsurface وما إلى ذلك)، ويكشف textTheme عن أنماط مُسمّاة (titleMedium وbodyLarge وما إلى ذلك). ويتكيّف الويدجت المكتوب بهذه الطريقة تلقائيًا مع السِّمة الفاتحة وكذلك الداكنة.
import 'package:flutter/material.dart';
class PriceTag extends StatelessWidget {
const PriceTag({super.key, required this.price});
final double price;
@override
Widget build(BuildContext context) {
final colors = Theme.of(context).colorScheme;
final text = Theme.of(context).textTheme;
return Container(
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 6,
),
decoration: BoxDecoration(
color: colors.primaryContainer,
borderRadius: BorderRadius.circular(8),
),
child: Text(
'$price €',
style: text.titleMedium?.copyWith(
color: colors.onPrimaryContainer,
),
),
);
}
}للمضيّ أبعد، اضبط سِمات المكوّنات: تقبل كل عائلة من الويدجات (أشرطة التطبيق، والأزرار، وحقول الإدخال) سِمة مخصّصة في ThemeData. تُعرِّف الحاشية الداخلية لأزرارك أو توسيط عناوينك مرة واحدة، فترث كل نسخة ذلك دون نمط محلي واحد.
import 'package:flutter/material.dart';
final ThemeData appTheme = ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.teal,
),
appBarTheme: const AppBarTheme(
centerTitle: true,
elevation: 0,
),
filledButtonTheme: FilledButtonThemeData(
style: FilledButton.styleFrom(
padding: const EdgeInsets.symmetric(
horizontal: 24,
vertical: 12,
),
),
),
);