Theme और ThemeData — Flutter में थीमीकरण की केंद्रीय प्रणालियाँ हैं, जो पूरे एप्लिकेशन के लिए वैश्विक रूप से रंग, फ़ॉन्ट, मार्जिन और कंपोनेंट शैलियों को सेट करने की अनुमति देती हैं। ThemeData एक कॉन्फ़िगरेशन ऑब्जेक्ट है जो theme पैरामीटर के माध्यम से MaterialApp को पास किया जाता है। आधिकारिक Flutter दस्तावेज़ (2026) के अनुसार, ThemeData का सही कॉन्फ़िगरेशन डुप्लिकेट स्टाइलिंग कोड को 70–80% तक कम करता है और सभी स्क्रीन पर एक समान दृश्य स्वरूप सुनिश्चित करता है। अंतर्निहित इनहेरिटेंस सिस्टम Theme.of(context) के माध्यम से अलग-अलग विजेट के स्तर पर थीम को ओवरराइड करने की अनुमति देता है।
मुख्य बिंदु
ThemeData एक वर्ग है जिसमें Material एप्लिकेशन की दृश्य शैली का पूर्ण विवरण होता है। इसे theme या darkTheme पैरामीटर के माध्यम से MaterialApp को पास किया जाता है और सभी चाइल्ड विजेट इसे प्राप्त करते हैं। प्रत्येक Material Design विजेट अपनी शैलियाँ प्राप्त करने के लिए ThemeData का उपयोग करता है: बटन के रंग, AppBar के आकार, टेक्स्ट शैलियाँ, कार्ड के मार्जिन और आइकन।
ThemeData के केंद्र में ColorScheme है, जो primary, secondary, surface, error और अन्य रंगों को परिभाषित करता है। इन रंगों से सभी Material कंपोनेंट्स के लिए अवस्थाएँ (hover, focus, pressed) स्वचालित रूप से गणना की जाती हैं। उदाहरण के लिए, ElevatedButton पृष्ठभूमि के लिए primary रंग और टेक्स्ट के लिए onPrimary का उपयोग करता है — बिना किसी अतिरिक्त कॉन्फ़िगरेशन के।
Theme विजेट एक InheritedWidget है जो थीम को विजेट ट्री में नीचे प्रसारित करता है। कोई भी विजेट Theme.of(context) के माध्यम से वर्तमान थीम तक पहुँच सकता है, और Theme.copyWith या ThemeData.copyWith के माध्यम से ओवरराइड किए गए मानों के साथ मौजूदा थीम के आधार पर एक नई थीम भी बना सकता है।
निष्कर्ष: ThemeData एप्लिकेशन की शैलियों का एकमात्र स्रोत है। ThemeData को परिभाषित करके विकास शुरू करें — यह पूरे प्रोजेक्ट की दृश्य भाषा निर्धारित करता है और विभिन्न स्क्रीनों पर बिखरी हुई शैलियों को रोकता है।
ColorScheme Material 3 में थीमीकरण का केंद्रीय तत्व है। यह पुराने primarySwatch और primaryColor को बदलता है, जो सभी अवस्थाओं और कंपोनेंट्स के लिए रंगों का पूरा सेट प्रदान करता है।
ColorScheme में 12 मुख्य रंग होते हैं: primary, onPrimary, secondary, onSecondary, surface, onSurface, error, onError, background, onBackground, outline और shadow। प्रत्येक रंग के लिए हल्के और गहरे वेरिएंट स्वचालित रूप से गणना किए जाते हैं, साथ ही hover, focus, pressed और dragged अवस्थाओं के रंग भी। जब केवल primary निर्दिष्ट किया जाता है, तो फ्रेमवर्क ColorScheme.fromSeed के माध्यम से शेष रंगों को स्वचालित रूप से उत्पन्न करता है।
ColorScheme.fromSeed विधि (Material 3) एक आधार रंग seedColor लेती है और Material Design 3 एल्गोरिदम के आधार पर एक पूर्ण सामंजस्यपूर्ण पैलेट उत्पन्न करती है। यह पूरक और अनुरूप रंगों के मैन्युअल चयन की आवश्यकता को समाप्त करता है। बस एक प्राथमिक ब्रांड रंग पास करें, और ColorScheme.fromSeed पूरे Material सिस्टम के लिए एक सुसंगत पैलेट बनाता है।
निष्कर्ष: नए प्रोजेक्ट्स में, पैलेट उत्पन्न करने के लिए ColorScheme.fromSeed का उपयोग करें। Material 2 संगतता के लिए — primarySwatch का उपयोग करें। Material 3 के लिए ColorScheme न्यूनतम आवश्यकता है।
TextTheme ThemeData का एक हिस्सा है जो सभी हेडिंग स्तरों, उपशीर्षकों, मुख्य टेक्स्ट और लेबल के लिए टेक्स्ट शैलियों को परिभाषित करता है। Material Design 15 टेक्स्ट शैलियों को परिभाषित करता है: headlineLarge, headlineMedium, headlineSmall, titleLarge, titleMedium और अन्य।
टाइपोग्राफी या तो GoogleFonts के माध्यम से स्वचालित फ़ॉन्ट लोडिंग के लिए, या कस्टम TextStyle ऑब्जेक्ट्स के साथ अंतर्निहित Theme.of(context).textTheme के माध्यम से सेट की जाती है। GoogleFonts google_fonts पैकेज के माध्यम से सैकड़ों फ़ॉन्ट प्रदान करता है, जो पहले लोड के बाद उन्हें स्थानीय रूप से कैश करता है। विकल्प — pubspec.yaml के माध्यम से फ़ॉन्ट को प्रोजेक्ट की एसेट्स में एम्बेड करना है।
अनुकूली टाइपोग्राफी के लिए, TextTheme MediaQuery.textScaleFactor का समर्थन करता है — जब सिस्टम फ़ॉन्ट आकार बढ़ता है, तो सभी टेक्स्ट शैलियाँ आनुपातिक रूप से स्केल होती हैं। अतिरिक्त रूप से, MediaQuery.size.width के आधार पर isTest के माध्यम से विभिन्न फॉर्म फैक्टर के लिए अलग-अलग फ़ॉन्ट आकार सेट किए जा सकते हैं।
निष्कर्ष: ThemeData में TextTheme को परिभाषित करें और सभी टेक्स्ट तत्वों के लिए Theme.of(context).textTheme का उपयोग करें। यह फ़ॉन्ट एकरूपता सुनिश्चित करता है और वैश्विक टाइपोग्राफी परिवर्तनों को सरल बनाता है।
Theme एक InheritedWidget है जो थीम को पैरेंट से चाइल्ड तक प्रसारित करता है। कोई भी चाइल्ड विजेट Theme.of(context) के माध्यम से वर्तमान थीम पढ़ सकता है और ThemeData.copyWith के माध्यम से बदलावों के साथ अपनी कॉपी बना सकता है।
इनहेरिटेंस तंत्र: यदि कोई विजेट नए डेटा के साथ Theme में लपेटा गया है, तो उसके सभी वंशज ओवरराइड की गई थीम देखते हैं, जबकि इस आवरण के बाहर के विजेट मूल थीम देखते हैं। यह उदाहरण के लिए, किसी विशिष्ट स्क्रीन के लिए शैलियों को अलग करने की अनुमति देता है: हेडर संशोधित AppBarTheme के साथ एक कस्टम थीम का उपयोग करता है, जबकि बाकी एप्लिकेशन मानक थीम का उपयोग करता है।
Theme की नेस्टिंग असीमित हो सकती है। Flutter पदानुक्रमिक खोज का उपयोग करता है: Theme.of(context) को कॉल करने पर, फ्रेमवर्क पहले Theme तक ट्री में ऊपर जाता है और उसकी थीम लौटाता है। यदि कोई Theme नहीं मिलता — तो एक अपवाद फेंका जाता है। इसलिए, MaterialApp हमेशा एप्लिकेशन को Theme में लपेटता है।
निष्कर्ष: Theme इनहेरिटेंस शैली अलगाव के लिए एक लचीला तंत्र है। वैश्विक कॉन्फ़िगरेशन की नकल किए बिना अलग-अलग स्क्रीन के लिए थीम ओवरराइडिंग का उपयोग करें।
डार्क थीम Flutter की लाइट और डार्क थीम के बीच स्विच करने की अंतर्निहित क्षमता है। ThemeData MaterialApp के theme (लाइट) और darkTheme (डार्क) पैरामीटर में संग्रहीत होता है। themeMode पैरामीटर मोड को नियंत्रित करता है: ThemeMode.light (हमेशा लाइट), ThemeMode.dark (हमेशा डार्क) या ThemeMode.system (सिस्टम सेटिंग्स का अनुसरण करता है)।
डार्क थीम को लागू करते समय, सभी शैलियों को फिर से बनाने की आवश्यकता नहीं है। बस ColorScheme.fromSeed(seedColor, brightness: Brightness.dark) को darkTheme में पास करें। फ्रेमवर्क स्वचालित रूप से डार्क बैकग्राउंड के लिए रंगों को समायोजित करेगा: surface गहरा ग्रे हो जाता है, टेक्स्ट हल्का हो जाता है। अन्य उप-थीम (AppBarTheme, CardTheme, BottomNavigationBarTheme) लाइट संस्करण से विरासत में मिलती हैं जब तक कि स्पष्ट रूप से ओवरराइड न की जाएँ।
थीम के बीच सहज संक्रमण के लिए, Flutter AnimatedTheme के माध्यम से एनिमेशन प्रदान करता है। themeMode बदलने पर, रंग और शैलियाँ एनिमेट होती हैं, जो एक दृश्य रूप से सुखद संक्रमण बनाती हैं। AnimatedTheme एनिमेशन गति को कॉन्फ़िगर करने के लिए Duration और Curve का उपयोग करता है।
निष्कर्ष: डार्क थीम darkTheme और ColorScheme.fromSeed को brightness: Brightness.dark के साथ उपयोग करके कार्यान्वित की जाती है। उपयोगकर्ता की सिस्टम सेटिंग्स का पालन करने के लिए ThemeMode.system का उपयोग करें।
उदाहरण 1 — ColorScheme.fromSeed का उपयोग करके MaterialApp के माध्यम से वैश्विक थीम कॉन्फ़िगरेशन।
final ThemeData appTheme = ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.indigo,
brightness: Brightness.light,
),
appBarTheme: const AppBarTheme(
centerTitle: true,
elevation: 0,
),
cardTheme: const CardTheme(
elevation: 2,
margin: EdgeInsets.all(8),
),
);
return MaterialApp(
theme: appTheme,
themeMode: ThemeMode.system,
home: const MyHomePage(),
);
यह उदाहरण Material 3 के साथ ThemeData, इंडिगो-आधारित रंग योजना और कस्टम AppBar और Card शैलियाँ बनाता है। useMaterial3 Material 3 थीमिंग सिस्टम को सक्षम करता है, और ColorScheme.fromSeed पूर्ण पैलेट उत्पन्न करता है।
उदाहरण 2 — थीम तक पहुँच और एप्लिकेशन के एक भाग के लिए ओवरराइड करना।
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Column(
children: [
Text(
'Standard headline',
style: theme.textTheme.headlineMedium,
),
Theme(
data: theme.copyWith(
colorScheme: theme.colorScheme.copyWith(
primary: Colors.orange,
),
),
child: const SpecialSection(),
),
],
);
}
दूसरा उदाहरण शैलियों को पढ़ने के लिए Theme.of(context) का उपयोग और वैश्विक कॉन्फ़िगरेशन को बदले बिना ट्री के एक हिस्से में थीम को ओवरराइड करने के लिए copyWith के साथ Theme() का उपयोग दर्शाता है। Theme के अंदर SpecialSection नारंगी primary रंग प्राप्त करेगा, जबकि बाकी एप्लिकेशन मूल इंडिगो बनाए रखता है।
निष्कर्ष: वैश्विक थीम MaterialApp में सेट की जाती है, Theme.of(context) के माध्यम से एक्सेस की जाती है, और copyWith के साथ Theme के माध्यम से ओवरराइड की जाती है। Material 3 के लिए, ColorScheme.fromSeed का उपयोग करें।
गलती 1: Material 3 में ColorScheme के बजाय primarySwatch का उपयोग करना। primarySwatch पुराना हो चुका है और Material 3 में समर्थित नहीं है। primarySwatch के साथ useMaterial3: true का उपयोग करने पर, Flutter एक चेतावनी जारी करता है। समाधान: पैलेट जनरेशन के लिए ColorScheme.fromSeed पर स्विच करें।
गलती 2: Theme.of(context) का उपयोग करने के बजाय विजेट में रंगों को हार्डकोड करना। डेवलपर्स थीम से primary या secondary रंग के बजाय सीधे Container में Colors.blue लिखते हैं। थीम बदलने पर, ये रंग अपरिवर्तित रहते हैं, एकसमान शैली को तोड़ते हैं। समाधान: हमेशा Theme.of(context).colorScheme.primary या थीम से अन्य रंगों का उपयोग करें।
गलती 3: darkTheme की अनुपस्थिति। यदि एप्लिकेशन darkTheme को परिभाषित नहीं करता है, तो डिवाइस पर डार्क थीम चालू होने पर, Flutter स्वचालित रूप से लाइट थीम को अनुकूलित करने का प्रयास करता है, जो अक्सर खराब परिणाम देता है। समाधान: हमेशा MaterialApp में darkTheme पास करें, भले ही डार्क थीम प्राथमिकता न हो — यह उपयोगकर्ताओं के लिए महत्वपूर्ण UX है।
गलती 4: प्रत्येक build पर नई थीम बनाना। यदि ThemeData build विधि के अंदर बनाया जाता है, तो प्रत्येक विजेट पुनर्निर्माण एक नया थीम ऑब्जेक्ट बनाता है, जो InheritedWidget ऑप्टिमाइज़ेशन को तोड़ता है। समाधान: ThemeData को static फ़ील्ड या build के बाहर const कंस्ट्रक्टर में ले जाएँ।
निष्कर्ष: सही थीमीकरण के लिए एक केंद्रीकृत दृष्टिकोण की आवश्यकता होती है। ThemeData को स्थिरांक में ले जाएँ, थीम से रंग योजनाओं का उपयोग करें, और हमेशा दोनों थीम — लाइट और डार्क — को परिभाषित करें।
अक्सर पूछे जाने वाले प्रश्न
ThemeData कॉन्फ़िगरेशन डेटा (रंग, फ़ॉन्ट, शैलियाँ) है। Theme एक InheritedWidget है जो ThemeData को विजेट ट्री में नीचे भेजता है। Theme.of(context) वह ThemeData लौटाता है जिसे निकटतम Theme वर्तमान संदर्भ में प्रसारित करता है।
एप्लिकेशन स्थिति के माध्यम से MaterialApp में themeMode को नियंत्रित करें। स्थिति को ThemeMode.light से ThemeMode.dark में बदलें, और Flutter नई थीम के साथ पूरे ट्री का पुनर्निर्माण करेगा। सहज एनिमेशन के लिए, AnimatedTheme का उपयोग करें।
ColorScheme.fromSeed एक Material 3 विधि है जो एक आधार रंग (seedColor) लेती है और एक पूर्ण सामंजस्यपूर्ण पैलेट उत्पन्न करती है: primary, secondary, tertiary, surface, error और उनके on-वेरिएंट। यह एक ही ब्रांड रंग से एक सुसंगत रंग योजना प्राप्त करने की अनुमति देता है।
ThemeData के अंदर TextTheme के माध्यम से: प्रत्येक स्तर के लिए fontFamily के साथ TextStyle निर्दिष्ट करें। Google Fonts के लिए, google_fonts पैकेज का उपयोग करें, fontFamily को सीधे TextTheme में पास करें। स्थानीय फ़ॉन्ट के लिए — उन्हें fonts अनुभाग में pubspec.yaml के माध्यम से शामिल करें।
हाँ। स्क्रीन को copyWith के माध्यम से ओवरराइड किए गए डेटा के साथ Theme में लपेटें। इस Theme के अंदर सभी चाइल्ड विजेट संशोधित शैलियाँ प्राप्त करेंगे, जबकि बाकी एप्लिकेशन मूल थीम बनाए रखता है। यह कोई अतिरिक्त ओवरहेड नहीं बनाता है।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें