अपने Flutter ऐप्लिकेशन में होम स्क्रीन विजेट जोड़ना

1. परिचय

विजेट क्या होते हैं?

Flutter डेवलपर के लिए, विजेट का मतलब, Flutter फ़्रेमवर्क का इस्तेमाल करके बनाए गए यूज़र इंटरफ़ेस (यूआई) कॉम्पोनेंट से होता है. इस कोडलैब के हिसाब से, विजेट का मतलब ऐप्लिकेशन के मिनी वर्शन से है. यह ऐप्लिकेशन की जानकारी को ऐप्लिकेशन खोले बिना दिखाता है. Android पर, विजेट होम स्क्रीन पर दिखते हैं. iOS पर, इन्हें होम स्क्रीन, लॉक स्क्रीन या 'आज' व्यू में जोड़ा जा सकता है.

f0027e8a7d0237e0.png b991e79ea72c8b65.png

कोई विजेट कितना जटिल हो सकता है?

ज़्यादातर होम स्क्रीन विजेट आसान होते हैं. इनमें सामान्य टेक्स्ट, सामान्य ग्राफ़िक या Android पर सामान्य कंट्रोल शामिल हो सकते हैं. Android और iOS, दोनों ही यह तय करते हैं कि कौनसे यूज़र इंटरफ़ेस (यूआई) कॉम्पोनेंट और सुविधाओं का इस्तेमाल किया जा सकता है.

819b9fffd700e571.png 92d62ccfd17d770d.png

विजेट के लिए यूज़र इंटरफ़ेस (यूआई) बनाना

यूज़र इंटरफ़ेस (यूआई) से जुड़ी इन सीमाओं की वजह से, Flutter फ़्रेमवर्क का इस्तेमाल करके सीधे तौर पर होम स्क्रीन विजेट का यूज़र इंटरफ़ेस (यूआई) नहीं बनाया जा सकता. इसके बजाय, Jetpack Compose या SwiftUI जैसे प्लैटफ़ॉर्म फ़्रेमवर्क का इस्तेमाल करके बनाए गए विजेट को अपने Flutter ऐप्लिकेशन में जोड़ा जा सकता है. इस कोडलैब में, आपके ऐप्लिकेशन और विजेट के बीच संसाधनों को शेयर करने के उदाहरणों के बारे में बताया गया है. इससे जटिल यूज़र इंटरफ़ेस (यूआई) को फिर से लिखने से बचा जा सकता है.

आपको क्या बनाने को मिलेगा

इस कोडलैब में, home_widget पैकेज का इस्तेमाल करके, Android और iOS, दोनों के लिए होम स्क्रीन विजेट बनाए जाएंगे. ये विजेट, Flutter के एक सामान्य ऐप्लिकेशन के लिए बनाए जाएंगे. इस ऐप्लिकेशन की मदद से, लोग लेख पढ़ सकते हैं. आपके विजेट:

  • अपने Flutter ऐप्लिकेशन का डेटा दिखाएं.
  • Flutter ऐप्लिकेशन से शेयर की गई फ़ॉन्ट ऐसेट का इस्तेमाल करके टेक्स्ट दिखाना.
  • रेंडर किए गए फ़्लटर विजेट की इमेज दिखाएं.

a36b7ba379151101.png

इस फ़्लटर ऐप्लिकेशन में दो स्क्रीन (या राउट) शामिल हैं:

  • पहले में, हेडलाइन और जानकारी के साथ समाचार लेखों की सूची दिखाई गई है.
  • दूसरी इमेज में, CustomPaint का इस्तेमाल करके बनाए गए चार्ट के साथ पूरा लेख दिखाया गया है.

.

9c02f8b62c1faa3a.png d97d44051304cae4.png

आपको क्या सीखने को मिलेगा

  • iOS और Android पर होम स्क्रीन विजेट बनाने का तरीका.
  • होम स्क्रीन विजेट और Flutter ऐप्लिकेशन के बीच डेटा शेयर करने के लिए, home_widget पैकेज का इस्तेमाल कैसे करें.
  • कोड को फिर से लिखने की ज़रूरत को कैसे कम किया जाए.
  • Flutter ऐप्लिकेशन से होम स्क्रीन विजेट को अपडेट करने का तरीका.

2. डेवलपमेंट एनवायरमेंट सेट अप करना

दोनों प्लैटफ़ॉर्म के लिए, आपको Flutter SDK और एक आईडीई की ज़रूरत होगी. Flutter के साथ काम करने के लिए, अपने पसंदीदा आईडीई का इस्तेमाल किया जा सकता है. यह Dart Code और Flutter एक्सटेंशन के साथ Visual Studio Code हो सकता है. इसके अलावा, Flutter और Dart प्लगिन इंस्टॉल किए गए Android Studio या IntelliJ भी हो सकते हैं.

iOS की होम स्क्रीन पर विजेट बनाने के लिए:

  • इस कोडलैब को किसी फ़िज़िकल iOS डिवाइस या iOS सिम्युलेटर पर चलाया जा सकता है.
  • आपको Xcode IDE के साथ macOS सिस्टम को कॉन्फ़िगर करना होगा. इससे, आपके ऐप्लिकेशन का iOS वर्शन बनाने के लिए ज़रूरी कंपाइलर इंस्टॉल हो जाता है.

Android की होम स्क्रीन पर विजेट बनाने के लिए:

  • इस कोडलैब को किसी फ़िज़िकल Android डिवाइस या Android एम्युलेटर पर चलाया जा सकता है.
  • आपको Android Studio के साथ अपना डेवलपमेंट सिस्टम कॉन्फ़िगर करना होगा. इससे, आपके ऐप्लिकेशन का Android वर्शन बनाने के लिए ज़रूरी कंपाइलर इंस्टॉल हो जाता है.

स्टार्टर कोड पाना

GitHub से अपने प्रोजेक्ट का शुरुआती वर्शन डाउनलोड करना

कमांड लाइन से, GitHub रिपॉज़िटरी को flutter-codelabs डायरेक्ट्री में क्लोन करें:

$ git clone https://github.com/flutter/codelabs.git flutter-codelabs

रेपो को क्लोन करने के बाद, आपको इस कोडलैब का कोड, flutter-codelabs/homescreen_codelab डायरेक्ट्री में मिलेगा. इस डायरेक्ट्री में, कोडलैब के हर चरण के लिए पूरा किया गया प्रोजेक्ट कोड होता है.

स्टार्टर ऐप्लिकेशन खोलें

flutter-codelabs/homescreen_codelab/step_03 डायरेक्ट्री को अपने पसंदीदा IDE में खोलें.

पैकेज इंस्टॉल करना

सभी ज़रूरी पैकेज, प्रोजेक्ट की pubspec.yaml फ़ाइल में जोड़ दिए गए हों. प्रोजेक्ट की डिपेंडेंसी वापस पाने के लिए, यह कमांड चलाएं:

$ flutter pub get

3. होम स्क्रीन पर बुनियादी विजेट जोड़ना

सबसे पहले, नेटिव प्लैटफ़ॉर्म टूलिंग का इस्तेमाल करके, होम स्क्रीन विजेट जोड़ें.

iOS की होम स्क्रीन पर बुनियादी विजेट बनाना

अपने Flutter iOS ऐप्लिकेशन में ऐप्लिकेशन एक्सटेंशन जोड़ने का तरीका, SwiftUI या UIKit ऐप्लिकेशन में ऐप्लिकेशन एक्सटेंशन जोड़ने के तरीके जैसा ही होता है:

  1. अपने Flutter प्रोजेक्ट डायरेक्ट्री से, टर्मिनल विंडो में open ios/Runner.xcworkspace चलाएं. इसके अलावा, VSCode में ios फ़ोल्डर पर राइट क्लिक करें और Open in Xcode को चुनें. इससे आपके Flutter प्रोजेक्ट में डिफ़ॉल्ट Xcode वर्कस्पेस खुल जाता है.
  2. मेन्यू में जाकर, फ़ाइल → नया → टारगेट चुनें. इससे प्रोजेक्ट में एक नया टारगेट जुड़ जाता है.
  3. ऐसा करने पर, टेंप्लेट की सूची दिखती है. विजेट एक्सटेंशन चुनें.
  4. इस विजेट के लिए, प्रॉडक्ट का नाम बॉक्स में "NewsWidgets" टाइप करें. लाइव गतिविधि शामिल करें और कॉन्फ़िगरेशन इंटेंट शामिल करें, दोनों चेक बॉक्स से सही का निशान हटाएं.

सैंपल कोड की जांच करना

नया टारगेट जोड़ने पर, Xcode आपके चुने गए टेंप्लेट के आधार पर सैंपल कोड जनरेट करता है. जनरेट किए गए कोड और WidgetKit के बारे में ज़्यादा जानने के लिए, Apple के ऐप्लिकेशन एक्सटेंशन से जुड़े दस्तावेज़ देखें.

अपने सैंपल विजेट को डीबग और टेस्ट करना

  1. सबसे पहले, अपने Flutter ऐप्लिकेशन का कॉन्फ़िगरेशन अपडेट करें. जब आपको अपने Flutter ऐप्लिकेशन में नए पैकेज जोड़ने हों और Xcode से प्रोजेक्ट में टारगेट चलाना हो, तब आपको यह काम करना होगा. अपने ऐप्लिकेशन के कॉन्फ़िगरेशन को अपडेट करने के लिए, अपने Flutter ऐप्लिकेशन की डायरेक्ट्री में यह कमांड चलाएं:
$ flutter build ios --config-only
  1. टारगेट की सूची देखने के लिए, रनर पर क्लिक करें. अभी-अभी बनाए गए विजेट टारगेट, NewsWidgets को चुनें. इसके बाद, चलाएं पर क्लिक करें. iOS विजेट कोड में बदलाव करने पर, Xcode से विजेट टारगेट चलाएं.

bbb519df1782881d.png

  1. सिम्युलेटर या डिवाइस की स्क्रीन पर, होम स्क्रीन का बेसिक विजेट दिखना चाहिए. अगर आपको यह नहीं दिखता है, तो इसे स्क्रीन पर जोड़ा जा सकता है. होम स्क्रीन पर क्लिक करके रखें. इसके बाद, सबसे ऊपर बाएं कोने में मौजूद + पर क्लिक करें.

18eff1cae152014d.png

  1. ऐप्लिकेशन का नाम खोजें. इस कोडलैब के लिए, "Homescreen Widgets" खोजें

a0c00df87615493e.png

  1. होम स्क्रीन पर विजेट जोड़ने के बाद, उस पर समय दिखाने वाला सामान्य टेक्स्ट दिखेगा.

Android के लिए सामान्य विजेट बनाना

  1. Android में होम स्क्रीन विजेट जोड़ने के लिए, Android Studio में प्रोजेक्ट की बिल्ड फ़ाइल खोलें. यह फ़ाइल, android/build.gradle पर मौजूद होती है. इसके अलावा, VSCode में android फ़ोल्डर पर राइट क्लिक करें और Open in Android Studio को चुनें.
  2. प्रोजेक्ट बनने के बाद, सबसे ऊपर बाएं कोने में ऐप्लिकेशन डायरेक्ट्री ढूंढें. इस डायरेक्ट्री में, होम स्क्रीन पर दिखने वाला नया विजेट जोड़ें. डायरेक्ट्री पर राइट क्लिक करें. इसके बाद, New -> Widget -> App Widget को चुनें.

f19d8b7f95ab884e.png

  1. Android Studio में एक नया फ़ॉर्म दिखता है. अपनी होम स्क्रीन पर मौजूद विजेट के बारे में बुनियादी जानकारी जोड़ें. इसमें विजेट का क्लास नेम, प्लेसमेंट, साइज़, और सोर्स लैंग्वेज शामिल है

इस कोडलैब के लिए, ये वैल्यू सेट करें:

  • क्लास का नाम बॉक्स को NewsWidget पर ले जाएं
  • कम से कम चौड़ाई (सेल) ड्रॉपडाउन को 3 पर सेट करें
  • कम से कम ऊंचाई (सेल) ड्रॉपडाउन को 3 पर सेट करें

सैंपल कोड की जांच करना

फ़ॉर्म सबमिट करने पर, Android Studio कई फ़ाइलें बनाता है और उन्हें अपडेट करता है. इस कोडलैब से जुड़े बदलावों के बारे में नीचे दी गई टेबल में बताया गया है

कार्रवाई

टारगेट फ़ाइल

बदलें

अपडेट करें

AndroidManifest.xml

यह एक नया रिसीवर जोड़ता है, जो NewsWidget को रजिस्टर करता है.

बनाएं

res/layout/news_widget.xml

यह कुकी, होम स्क्रीन विजेट के यूज़र इंटरफ़ेस (यूआई) को तय करती है.

बनाएं

res/xml/news_widget_info.xml

यह कुकी, होम स्क्रीन विजेट के कॉन्फ़िगरेशन के बारे में जानकारी देती है. इस फ़ाइल में, अपने विजेट के डाइमेंशन या नाम में बदलाव किया जा सकता है.

बनाएं

java/com/example/homescreen_widgets/NewsWidget.kt

इसमें होम स्क्रीन विजेट में फ़ंक्शन जोड़ने के लिए, Kotlin कोड होता है.

इस कोडलैब में, इन फ़ाइलों के बारे में ज़्यादा जानकारी दी गई है.

अपने सैंपल विजेट को डीबग और टेस्ट करना

अब अपना ऐप्लिकेशन चलाएं और होम स्क्रीन विजेट देखें. ऐप्लिकेशन बनाने के बाद, अपने Android डिवाइस की ऐप्लिकेशन चुनने वाली स्क्रीन पर जाएं. इसके बाद, इस Flutter प्रोजेक्ट के आइकॉन को दबाकर रखें. पॉप-अप मेन्यू से, विजेट चुनें.

dff7c9f9f85ef1c7.png

Android डिवाइस या एम्युलेटर पर, Android के लिए होम स्क्रीन पर दिखने वाला डिफ़ॉल्ट विजेट दिखता है.

4. अपने Flutter ऐप्लिकेशन से होम स्क्रीन विजेट पर डेटा भेजना

आपने जो होम स्क्रीन विजेट बनाया है उसे अपनी पसंद के मुताबिक बनाया जा सकता है. होम स्क्रीन पर मौजूद विजेट को अपडेट करें, ताकि किसी लेख की हेडलाइन और खास जानकारी दिखाई जा सके. इस स्क्रीनशॉट में, होम स्क्रीन पर मौजूद विजेट का उदाहरण दिखाया गया है. इसमें हेडलाइन और खास जानकारी दिख रही है.

acb90343a3e51b6d.png

अपने ऐप्लिकेशन और होम स्क्रीन विजेट के बीच डेटा ट्रांसफ़र करने के लिए, आपको Dart और नेटिव कोड लिखना होगा. इस सेक्शन में, इस प्रोसेस को तीन हिस्सों में बांटा गया है:

  1. अपने Flutter ऐप्लिकेशन में ऐसा Dart कोड लिखना जिसे Android और iOS, दोनों इस्तेमाल कर सकें
  2. iOS की नेटिव सुविधा जोड़ना
  3. Android के नेटिव फ़ंक्शन जोड़ना

iOS ऐप्लिकेशन ग्रुप का इस्तेमाल करना

iOS पैरंट ऐप्लिकेशन और विजेट एक्सटेंशन के बीच डेटा शेयर करने के लिए, दोनों टारगेट एक ही ऐप्लिकेशन ग्रुप से जुड़े होने चाहिए. ऐप्लिकेशन ग्रुप के बारे में ज़्यादा जानने के लिए, Apple का ऐप्लिकेशन ग्रुप से जुड़ा दस्तावेज़ देखें.

बंडल आईडी अपडेट करने के लिए:

Xcode में, टारगेट की सेटिंग पर जाएं. Signing & Capabilities टैब में जाकर देखें कि आपकी टीम और बंडल आइडेंटिफ़ायर सेट है या नहीं.

Xcode में, App Group को Runner टारगेट और NewsWidgetExtension टारगेट दोनों में जोड़ें:

+ सुविधा -> ऐप्लिकेशन ग्रुप चुनें और नया ऐप्लिकेशन ग्रुप जोड़ें. रनर (पैरंट ऐप्लिकेशन) टारगेट और विजेट टारगेट, दोनों के लिए इस प्रोसेस को दोहराएं.

135e1a8c4652dac.png

Dart कोड जोड़ना

iOS और Android, दोनों तरह के ऐप्लिकेशन, Flutter ऐप्लिकेशन के साथ कई तरीकों से डेटा शेयर कर सकते हैं.इन ऐप्लिकेशन के साथ कम्यूनिकेट करने के लिए, डिवाइस के लोकल key/value स्टोर का इस्तेमाल करें. iOS इस स्टोर को UserDefaults कहता है और Android इसे SharedPreferences कहता है. home_widget पैकेज इन एपीआई को रैप करता है, ताकि किसी भी प्लैटफ़ॉर्म पर डेटा को आसानी से सेव किया जा सके. साथ ही, यह होम स्क्रीन विजेट को अपडेट किया गया डेटा पाने की सुविधा देता है.

707ae86f6650ac55.png

हेडलाइन और जानकारी का डेटा, news_data.dart फ़ाइल से लिया जाता है. इस फ़ाइल में मॉक डेटा और NewsArticle डेटा क्लास शामिल है.

lib/news_data.dart

class NewsArticle {
  final String title;
  final String description;
  final String? articleText;

  NewsArticle({
    required this.title,
    required this.description,
    this.articleText = loremIpsum,
  });
}

हेडलाइन और ब्यौरे की वैल्यू अपडेट करना

अपने Flutter ऐप्लिकेशन से होम स्क्रीन विजेट को अपडेट करने की सुविधा जोड़ने के लिए, lib/home_screen.dart फ़ाइल पर जाएं. फ़ाइल के कॉन्टेंट की जगह यह कोड डालें. इसके बाद, <YOUR APP GROUP> को अपने ऐप्लिकेशन ग्रुप के आइडेंटिफ़ायर से बदलें.

lib/home_screen.dart

import 'package:flutter/material.dart';
import 'package:home_widget/home_widget.dart';             // Add this import

import 'article_screen.dart';
import 'news_data.dart';

// TODO: Replace with your App Group ID
const String appGroupId = '<YOUR APP GROUP>';              // Add from here
const String iOSWidgetName = 'NewsWidgets';
const String androidWidgetName = 'NewsWidget';             // To here.

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

void updateHeadline(NewsArticle newHeadline) {             // Add from here
  // Save the headline data to the widget
  HomeWidget.saveWidgetData<String>('headline_title', newHeadline.title);
  HomeWidget.saveWidgetData<String>(
      'headline_description', newHeadline.description);
  HomeWidget.updateWidget(
    iOSName: iOSWidgetName,
    androidName: androidWidgetName,
  );
}                                                          // To here.

class _MyHomePageState extends State<MyHomePage> {

  @override                                                // Add from here
  void initState() {
    super.initState();

    HomeWidget.setAppGroupId(appGroupId);

    // Mock read in some data and update the headline
    final newHeadline = getNewsStories()[0];
    updateHeadline(newHeadline);
  }                                                        // To here.

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
            title: const Text('Top Stories'),
            centerTitle: false,
            titleTextStyle: const TextStyle(
                fontSize: 30,
                fontWeight: FontWeight.bold,
                color: Colors.black)),
        body: ListView.separated(
          separatorBuilder: (context, idx) {
            return const Divider();
          },
          itemCount: getNewsStories().length,
          itemBuilder: (context, idx) {
            final article = getNewsStories()[idx];
            return ListTile(
              key: Key('$idx ${article.hashCode}'),
              title: Text(article.title!),
              subtitle: Text(article.description!),
              onTap: () {
                Navigator.of(context).push(
                  MaterialPageRoute(
                    builder: (context) {
                      return ArticleScreen(article: article);
                    },
                  ),
                );
              },
            );
          },
        ));
  }
}

updateHeadline फ़ंक्शन, कुंजी/वैल्यू के जोड़े को आपके डिवाइस के लोकल स्टोरेज में सेव करता है. headline_title कुंजी में newHeadline.title की वैल्यू होती है. headline_description कुंजी में newHeadline.description की वैल्यू होती है. यह फ़ंक्शन, नेटिव प्लैटफ़ॉर्म को यह सूचना भी देता है कि होम स्क्रीन विजेट के लिए नया डेटा वापस पाया जा सकता है और उसे रेंडर किया जा सकता है.

floatingActionButton में बदलाव करना

floatingActionButton दबाने पर, updateHeadline फ़ंक्शन को कॉल करें. इसे इस तरह दिखाया गया है:

lib/article_screen.dart

// New: import the updateHeadline function
import 'home_screen.dart';

...

floatingActionButton: FloatingActionButton.extended(
        onPressed: () {
          ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
            content: Text('Updating home screen widget...'),
          ));
          // New: call updateHeadline
          updateHeadline(widget.article);
        },
        label: const Text('Update Homescreen'),
      ),
...

इस बदलाव के बाद, जब कोई व्यक्ति लेख वाले पेज पर मौजूद हेडलाइन अपडेट करें बटन को दबाता है, तो होम स्क्रीन विजेट की जानकारी अपडेट हो जाती है.

लेख का डेटा दिखाने के लिए, iOS कोड को अपडेट करना

iOS के लिए होम स्क्रीन विजेट को अपडेट करने के लिए, Xcode का इस्तेमाल करें.

Xcode में NewsWidgets.swift फ़ाइल खोलें:

TimelineEntryको कॉन्फ़िगर करें.

SimpleEntry स्ट्रक्चर की जगह यह कोड डालें:

ios/NewsWidgets/NewsWidgets.swift

// The date and any data you want to pass into your app must conform to TimelineEntry
struct NewsArticleEntry: TimelineEntry {
    let date: Date
    let title: String
    let description:String
}

यह NewsArticleEntry स्ट्रक्चर, अपडेट होने पर होम स्क्रीन विजेट में पास किए जाने वाले इनकमिंग डेटा को तय करता है. TimelineEntry टाइप के लिए, तारीख का पैरामीटर ज़रूरी है.TimelineEntry प्रोटोकॉल के बारे में ज़्यादा जानने के लिए, Apple के TimelineEntry दस्तावेज़ देखें.

View जिसमें कॉन्टेंट दिखता है में बदलाव करना

होम स्क्रीन पर मौजूद विजेट में बदलाव करके, तारीख की जगह समाचार लेख की हेडलाइन और ब्यौरा दिखाएं. SwiftUI में टेक्स्ट दिखाने के लिए, Text व्यू का इस्तेमाल करें. SwiftUI में व्यू को एक-दूसरे के ऊपर स्टैक करने के लिए, VStack व्यू का इस्तेमाल करें.

जनरेट किए गए NewsWidgetEntryView व्यू की जगह यह कोड डालें:

ios/NewsWidgets/NewsWidgets.swift

//View that holds the contents of the widget
struct NewsWidgetsEntryView : View {
    var entry: Provider.Entry

    var body: some View {
      VStack {
        Text(entry.title)
        Text(entry.description)
      }
    }
}

प्रोवाइडर में बदलाव करके, होम स्क्रीन विजेट को यह बताना कि उसे कब और कैसे अपडेट करना है

मौजूदा Provider की जगह यह कोड डालें. इसके बाद, <YOUR APP GROUP> की जगह पर, अपने ऐप्लिकेशन ग्रुप का आइडेंटिफ़ायर डालें:

ios/NewsWidgets/NewsWidgets.swift

struct Provider: TimelineProvider {

// Placeholder is used as a placeholder when the widget is first displayed
    func placeholder(in context: Context) -> NewsArticleEntry {
//      Add some placeholder title and description, and get the current date
      NewsArticleEntry(date: Date(), title: "Placeholder Title", description: "Placeholder description")
    }

// Snapshot entry represents the current time and state
    func getSnapshot(in context: Context, completion: @escaping (NewsArticleEntry) -> ()) {
      let entry: NewsArticleEntry
      if context.isPreview{
        entry = placeholder(in: context)
      }
      else{
        //      Get the data from the user defaults to display
        let userDefaults = UserDefaults(suiteName: <YOUR APP GROUP>)
        let title = userDefaults?.string(forKey: "headline_title") ?? "No Title Set"
        let description = userDefaults?.string(forKey: "headline_description") ?? "No Description Set"
        entry = NewsArticleEntry(date: Date(), title: title, description: description)
      }
        completion(entry)
    }

//    getTimeline is called for the current and optionally future times to update the widget
    func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
//      This just uses the snapshot function you defined earlier
      getSnapshot(in: context) { (entry) in
// atEnd policy tells widgetkit to request a new entry after the date has passed
        let timeline = Timeline(entries: [entry], policy: .atEnd)
                  completion(timeline)
              }
    }
}

पिछले कोड में मौजूद Provider, TimelineProvider के मुताबिक है. Provider के तीन अलग-अलग तरीके हैं:

  1. जब उपयोगकर्ता पहली बार होम स्क्रीन विजेट की झलक देखता है, तब placeholder तरीके से प्लेसहोल्डर एंट्री जनरेट होती है.

45a0f64240c12efe.png

  1. getSnapshot तरीका, उपयोगकर्ता की डिफ़ॉल्ट सेटिंग से डेटा पढ़ता है और मौजूदा समय के लिए एंट्री जनरेट करता है.
  2. getTimeline वाला तरीका, टाइमलाइन की एंट्री दिखाता है. यह तब काम आता है, जब आपको पता हो कि कॉन्टेंट को कब-कब अपडेट करना है. यह कोडलैब, मौजूदा स्थिति पाने के लिए getSnapshot फ़ंक्शन का इस्तेमाल करता है. .atEnd तरीके से, होम स्क्रीन विजेट को यह निर्देश दिया जाता है कि वह मौजूदा समय के बाद डेटा को रीफ़्रेश करे.

NewsWidgets_Previews को कमेंट आउट करें

इस कोडलैब में, झलक का इस्तेमाल करने के बारे में नहीं बताया गया है. SwiftUI होम स्क्रीन विजेट की झलक देखने के बारे में ज़्यादा जानने के लिए, विजेट डीबग करने से जुड़े Apple के दस्तावेज़ देखें.

सभी फ़ाइलें सेव करें और ऐप्लिकेशन और विजेट टारगेट को फिर से चलाएं.

यह पुष्टि करने के लिए कि ऐप्लिकेशन और होम स्क्रीन विजेट काम करते हैं, टारगेट को फिर से चलाएं.

  1. ऐप्लिकेशन टारगेट चलाने के लिए, Xcode में ऐप्लिकेशन स्कीमा चुनें.
  2. एक्सटेंशन टारगेट चलाने के लिए, Xcode में एक्सटेंशन स्कीमा चुनें.
  3. ऐप्लिकेशन में किसी लेख वाले पेज पर जाएं.
  4. हेडलाइन अपडेट करने के लिए, बटन पर क्लिक करें. होम स्क्रीन विजेट में भी हेडलाइन अपडेट होनी चाहिए.

Android कोड अपडेट करना

होम स्क्रीन विजेट का एक्सएमएल जोड़ें.

Android Studio में, पिछले चरण में जनरेट की गई फ़ाइलों को अपडेट करें.res/layout/news_widget.xml फ़ाइल खोलें. इससे आपकी होम स्क्रीन पर दिखने वाले विजेट का स्ट्रक्चर और लेआउट तय होता है. सबसे ऊपर दाएं कोने में मौजूद, कोड को चुनें. इसके बाद, उस फ़ाइल के कॉन्टेंट को इस कोड से बदलें:

android/app/res/layout/news_widget.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
   android:id="@+id/widget_container"
   style="@style/Widget.Android.AppWidget.Container"
   android:layout_width="wrap_content"
   android:layout_height="match_parent"
   android:background="@android:color/white"
   android:theme="@style/Theme.Android.AppWidgetContainer">
   
   <TextView
       android:id="@+id/headline_title"
       style="@style/Widget.Android.AppWidget.InnerView"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignParentStart="true"
       android:layout_alignParentLeft="true"
       android:layout_marginStart="8dp"
       android:layout_marginLeft="8dp"
       android:background="@android:color/white"
       android:text="Title"
       android:textSize="20sp"
       android:textStyle="bold" />

   <TextView
       android:id="@+id/headline_description"
       style="@style/Widget.Android.AppWidget.InnerView"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_below="@+id/headline_title"
       android:layout_alignParentStart="true"
       android:layout_alignParentLeft="true"
       android:layout_marginStart="8dp"
       android:layout_marginLeft="8dp"
       android:layout_marginTop="4dp"
       android:background="@android:color/white"
       android:text="Title"
       android:textSize="16sp" />

</RelativeLayout>

इस एक्सएमएल में दो टेक्स्ट व्यू तय किए गए हैं. एक लेख की हेडलाइन के लिए और दूसरा लेख के ब्यौरे के लिए. इन टेक्स्ट व्यू में स्टाइलिंग भी तय की जाती है. इस कोडलैब के दौरान, आपको इस फ़ाइल पर वापस आना होगा.

NewsWidget की सुविधाओं को अपडेट करना

NewsWidget.kt Kotlin सोर्स कोड फ़ाइल खोलें. इस फ़ाइल में, AppWidgetProvider क्लास को बढ़ाने वाली NewsWidget नाम की जनरेट की गई क्लास मौजूद है.

NewsWidget क्लास में, इसकी सुपर क्लास के तीन तरीके शामिल हैं. आपको onUpdate का तरीका बदलना होगा. Android, विजेट के लिए इस तरीके को तय समय पर कॉल करता है.

NewsWidget.kt फ़ाइल के कॉन्टेंट की जगह यह कोड डालें:

android/app/java/com.mydomain.homescreen_widgets/NewsWidget.kt

// Import will depend on App ID.
package com.mydomain.homescreen_widgets

import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.Context
import android.widget.RemoteViews

// New import.
import es.antonborri.home_widget.HomeWidgetPlugin


/**
 * Implementation of App Widget functionality.
 */
class NewsWidget : AppWidgetProvider() {
    override fun onUpdate(
            context: Context,
            appWidgetManager: AppWidgetManager,
            appWidgetIds: IntArray,
    ) {
        for (appWidgetId in appWidgetIds) {
            // Get reference to SharedPreferences
            val widgetData = HomeWidgetPlugin.getData(context)
            val views = RemoteViews(context.packageName, R.layout.news_widget).apply {

                val title = widgetData.getString("headline_title", null)
                setTextViewText(R.id.headline_title, title ?: "No title set")

                val description = widgetData.getString("headline_description", null)
                setTextViewText(R.id.headline_description, description ?: "No description set")
            }

            appWidgetManager.updateAppWidget(appWidgetId, views)
        }
    }
}

अब, जब onUpdate को कॉल किया जाता है, तो Android, the widgetData.getString() तरीके का इस्तेमाल करके लोकल स्टोरेज से नई वैल्यू पाता है. इसके बाद, होम स्क्रीन विजेट पर दिखने वाले टेक्स्ट को बदलने के लिए, setTextViewText को कॉल करता है.

अपडेट की जांच करना

ऐप्लिकेशन को टेस्ट करें, ताकि यह पक्का किया जा सके कि होम स्क्रीन पर मौजूद विजेट, नए डेटा के साथ अपडेट हो रहे हैं. डेटा अपडेट करने के लिए, लेख वाले पेजों पर मौजूद होम स्क्रीन अपडेट करें FloatingActionButton का इस्तेमाल करें. आपकी होम स्क्रीन पर मौजूद विजेट, लेख के टाइटल के साथ अपडेट होना चाहिए.

5ce1c9914b43ad79.png

5. iOS होम स्क्रीन विजेट में, Flutter ऐप्लिकेशन के कस्टम फ़ॉन्ट इस्तेमाल करना

अब तक, आपने होम स्क्रीन विजेट को Flutter ऐप्लिकेशन से मिले डेटा को पढ़ने के लिए कॉन्फ़िगर किया है. Flutter ऐप्लिकेशन में एक कस्टम फ़ॉन्ट शामिल होता है. इसका इस्तेमाल होम स्क्रीन विजेट में किया जा सकता है. iOS की होम स्क्रीन पर मौजूद विजेट में, कस्टम फ़ॉन्ट का इस्तेमाल किया जा सकता है. Android पर, होम स्क्रीन विजेट में कस्टम फ़ॉन्ट इस्तेमाल करने की सुविधा उपलब्ध नहीं है.

iOS कोड अपडेट करना

Flutter, अपनी ऐसेट को iOS ऐप्लिकेशन के mainBundle में सेव करता है. इस बंडल में मौजूद ऐसेट को, होम स्क्रीन विजेट के कोड से ऐक्सेस किया जा सकता है.

NewsWidgets.swift फ़ाइल में मौजूद NewsWidgetsEntryView स्ट्रक्चर में, ये बदलाव करें

Flutter ऐसेट डायरेक्ट्री का पाथ पाने के लिए, हेल्पर फ़ंक्शन बनाएं:

ios/NewsWidgets/NewsWidgets.swift

struct NewsWidgetsEntryView : View {
   ...

   // New: Add the helper function.
   var bundle: URL {
           let bundle = Bundle.main
           if bundle.bundleURL.pathExtension == "appex" {
               // Peel off two directory levels - MY_APP.app/PlugIns/MY_APP_EXTENSION.appex
               var url = bundle.bundleURL.deletingLastPathComponent().deletingLastPathComponent()
               url.append(component: "Frameworks/App.framework/flutter_assets")
               return url
           }
           return bundle.bundleURL
       }
   ...
}

कस्टम फ़ॉन्ट फ़ाइल के यूआरएल का इस्तेमाल करके, फ़ॉन्ट रजिस्टर करें.

ios/NewsWidgets/NewsWidgets.swift

struct NewsWidgetsEntryView : View {
   ...

   // New: Register the font.
   init(entry: Provider.Entry){
     self.entry = entry
     CTFontManagerRegisterFontsForURL(bundle.appending(path: "/fonts/Chewy-Regular.ttf") as CFURL, CTFontManagerScope.process, nil)
   }
   ...
}

कस्टम फ़ॉन्ट का इस्तेमाल करने के लिए, हेडलाइन के टेक्स्ट व्यू को अपडेट करें.

ios/NewsWidgets/NewsWidgets.swift

struct NewsWidgetsEntryView : View {
   ...


   var body: some View {
    VStack {
      // Update the following line.
      Text(entry.title).font(Font.custom("Chewy", size: 13))
      Text(entry.description)
    }
   }
   ...
}

होम स्क्रीन विजेट चलाने पर, अब यह हेडलाइन के लिए कस्टम फ़ॉन्ट का इस्तेमाल करता है. यह फ़ॉन्ट, यहां दी गई इमेज में दिखाया गया है:

93f8b9d767aacfb2.png

6. Flutter विजेट को इमेज के तौर पर रेंडर करना

इस सेक्शन में, आपको अपने Flutter ऐप्लिकेशन से एक ग्राफ़ को होम स्क्रीन विजेट के तौर पर दिखाना होगा.

यह विजेट, होम स्क्रीन पर दिखाए गए टेक्स्ट से ज़्यादा मुश्किल है. नेटिव यूज़र इंटरफ़ेस (यूआई) कॉम्पोनेंट का इस्तेमाल करके, Flutter चार्ट को फिर से बनाने के बजाय, उसे इमेज के तौर पर दिखाना ज़्यादा आसान है.

अपनी होम स्क्रीन के विजेट को कोड करें, ताकि आपके फ़्लटर चार्ट को PNG फ़ाइल के तौर पर रेंडर किया जा सके. होम स्क्रीन पर मौजूद विजेट में, उस इमेज को दिखाया जा सकता है.

Dart कोड लिखना

Dart साइड पर, home_widget पैकेज से renderFlutterWidget तरीका जोड़ें. इस तरीके में एक विजेट, एक फ़ाइल का नाम, और एक कुंजी शामिल होती है. यह Flutter विजेट की इमेज दिखाता है और उसे शेयर किए गए कंटेनर में सेव करता है. अपने कोड में इमेज का नाम दें. साथ ही, यह पक्का करें कि होम स्क्रीन विजेट, कंटेनर को ऐक्सेस कर सके. key, फ़ाइल के पूरे पाथ को डिवाइस के लोकल स्टोरेज में स्ट्रिंग के तौर पर सेव करता है. इससे होम स्क्रीन विजेट को फ़ाइल ढूंढने की अनुमति मिलती है. ऐसा तब होता है, जब डार्ट कोड में फ़ाइल का नाम बदल जाता है.

इस कोडलैब के लिए, lib/article_screen.dart फ़ाइल में मौजूद LineChart क्लास, चार्ट को दिखाती है. इसका बिल्ड मेथड, एक CustomPainter दिखाता है. यह CustomPainter, इस चार्ट को स्क्रीन पर पेंट करता है.

इस सुविधा को लागू करने के लिए, lib/article_screen.dart फ़ाइल खोलें. home_widget पैकेज इंपोर्ट करें. इसके बाद, _ArticleScreenState क्लास में मौजूद कोड की जगह यह कोड डालें:

lib/article_screen.dart

import 'package:flutter/material.dart';
// New: import the home_widget package.
import 'package:home_widget/home_widget.dart';

import 'home_screen.dart';
import 'news_data.dart';

...

class _ArticleScreenState extends State<ArticleScreen> {
  // New: add this GlobalKey
  final _globalKey = GlobalKey();
  String? imagePath;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.article.title!),
      ),
      // New: add this FloatingActionButton
      floatingActionButton: FloatingActionButton.extended(
        onPressed: () async {
          if (_globalKey.currentContext != null) {
            var path = await HomeWidget.renderFlutterWidget(
              const LineChart(),
              fileName: 'screenshot',
              key: 'filename',
              logicalSize: _globalKey.currentContext!.size,
              pixelRatio:
                  MediaQuery.of(_globalKey.currentContext!).devicePixelRatio,
            );
            setState(() {
              imagePath = path as String?;
            });
          }
          updateHeadline(widget.article);
        },
        label: const Text('Update Homescreen'),
      ),
      body: ListView(
        padding: const EdgeInsets.all(16.0),
        children: [
          Text(
            widget.article.description!,
            style: Theme.of(context).textTheme.titleMedium,
          ),
          const SizedBox(height: 20.0),
          Text(widget.article.articleText!),
          const SizedBox(height: 20.0),
          Center(
            // New: Add this key
            key: _globalKey,
            child: const LineChart(),
          ),
          const SizedBox(height: 20.0),
          Text(widget.article.articleText!),
        ],
      ),
    );
  }
}

इस उदाहरण में, _ArticleScreenState क्लास में तीन बदलाव किए गए हैं.

GlobalKey बनाता है

GlobalKey को विजेट का कॉन्टेक्स्ट मिलता है. विजेट का साइज़ पाने के लिए, यह ज़रूरी है.

lib/article_screen.dart

class _ArticleScreenState extends State<ArticleScreen> {
   // New: add this GlobalKey
   final _globalKey = GlobalKey();
   ...
}

Adds imagePath

imagePath प्रॉपर्टी, इमेज की उस जगह की जानकारी सेव करती है जहां Flutter विजेट रेंडर किया जाता है.

lib/article_screen.dart

class _ArticleScreenState extends State<ArticleScreen> {
   ...
   // New: add this imagePath
   String? imagePath;
   ...
}

विजेट में कुंजी जोड़ता है, ताकि उसे रेंडर किया जा सके

_globalKey में, इमेज पर रेंडर किया गया Flutter विजेट होता है. इस मामले में, Flutter विजेट वह सेंटर है जिसमें LineChart शामिल है.

lib/article_screen.dart

class _ArticleScreenState extends State<ArticleScreen> {
   ...
   Center(
      // New: Add this key
 key: _globalKey,
 child: const LineChart(),
   ),
   ...
}
  1. इस विकल्प से, विजेट को इमेज के तौर पर सेव किया जाता है

जब उपयोगकर्ता floatingActionButton पर क्लिक करता है, तब renderFlutterWidget तरीके को कॉल किया जाता है. इस तरीके से, जनरेट हुई PNG फ़ाइल को शेयर की गई कंटेनर डायरेक्ट्री में "screenshot" के तौर पर सेव किया जाता है. यह तरीका, डिवाइस स्टोरेज में फ़ाइल नाम की कुंजी के तौर पर इमेज का पूरा पाथ भी सेव करता है.

lib/article_screen.dart

class _ArticleScreenState extends State<ArticleScreen> {
   ...
   floatingActionButton: FloatingActionButton.extended(
 onPressed: () async {
   if (_globalKey.currentContext != null) {
     var path = await HomeWidget.renderFlutterWidget(
       LineChart(),
       fileName: 'screenshot',
       key: 'filename',
       logicalSize: _globalKey.currentContext!.size,
       pixelRatio:
         MediaQuery.of(_globalKey.currentContext!).devicePixelRatio,
     );
     setState(() {
        imagePath = path as String?;
     });
    }
  updateHeadline(widget.article);
  },
   ...
}

iOS कोड अपडेट करना

iOS के लिए, कोड को अपडेट करें, ताकि स्टोरेज से फ़ाइल का पाथ मिल सके. साथ ही, SwiftUI का इस्तेमाल करके फ़ाइल को इमेज के तौर पर दिखाया जा सके.

NewsWidgets.swift फ़ाइल खोलें और ये बदलाव करें:

NewsArticleEntry struct में filename और displaySize जोड़ें

filename प्रॉपर्टी में वह स्ट्रिंग होती है जो इमेज फ़ाइल के पाथ को दिखाती है. displaySize प्रॉपर्टी, उपयोगकर्ता के डिवाइस पर होम स्क्रीन विजेट का साइज़ सेव करती है. होम स्क्रीन विजेट का साइज़, context से तय होता है.

ios/NewsWidgets/NewsWidgets.swift

struct NewsArticleEntry: TimelineEntry {
   ...

   // New: add the filename and displaySize.
   let filename: String
   let displaySize: CGSize
}

placeholder फ़ंक्शन को अपडेट करना

इसमें filename और displaySize प्लेसहोल्डर शामिल करें.

ios/NewsWidgets/NewsWidgets.swift

func placeholder(in context: Context) -> NewsArticleEntry {
      NewsArticleEntry(date: Date(), title: "Placeholder Title", description: "Placeholder description", filename: "No screenshot available",  displaySize: context.displaySize)
    }

getSnapshot में userDefaults से फ़ाइल का नाम पाएं

इससे होम स्क्रीन विजेट के अपडेट होने पर, filename वेरिएबल को userDefaults स्टोरेज में मौजूद filename वैल्यू पर सेट किया जाता है.

ios/NewsWidgets/NewsWidgets.swift

func getSnapshot(
   ...

   let title = userDefaults?.string(forKey: "headline_title") ?? "No Title Set"
   let description = userDefaults?.string(forKey: "headline_description") ?? "No Description Set"
   // New: get fileName from key/value store
   let filename = userDefaults?.string(forKey: "filename") ?? "No screenshot available"
   ...
)

ChartImage बनाएं जो किसी पाथ से इमेज दिखाता हो

ChartImage व्यू, Dart साइड पर जनरेट की गई फ़ाइल के कॉन्टेंट से एक इमेज बनाता है. यहां, फ़्रेम के साइज़ को 50% पर सेट किया गया है.

ios/NewsWidgets/NewsWidgets.swift

struct NewsWidgetsEntryView : View {
   ...

   // New: create the ChartImage view
   var ChartImage: some View {
        if let uiImage = UIImage(contentsOfFile: entry.filename) {
            let image = Image(uiImage: uiImage)
                .resizable()
                .frame(width: entry.displaySize.height*0.5, height: entry.displaySize.height*0.5, alignment: .center)
            return AnyView(image)
        }
        print("The image file could not be loaded")
        return AnyView(EmptyView())
    }
   ...
}

NewsWidgetsEntryView के मुख्य हिस्से में ChartImage का इस्तेमाल करें

ChartImage को होम स्क्रीन विजेट में दिखाने के लिए, ChartImage व्यू को NewsWidgetsEntryView के मुख्य हिस्से में जोड़ें.

ios/NewsWidgets/NewsWidgets.swift

VStack {
   Text(entry.title).font(Font.custom("Chewy", size: 13))
   Text(entry.description).font(.system(size: 12)).padding(10)
   // New: add the ChartImage to the NewsWidgetEntryView
   ChartImage
}

बदलावों को आज़माना

बदलावों की जांच करने के लिए, Xcode से अपने Flutter ऐप्लिकेशन (Runner) टारगेट और एक्सटेंशन टारगेट, दोनों को फिर से चलाएं. इमेज देखने के लिए, ऐप्लिकेशन में लेख के किसी पेज पर जाएँ और होम स्क्रीन विजेट को अपडेट करने के लिए बटन दबाएँ.

33bdfe2cce908c48.png

Android कोड अपडेट करना

Android कोड, iOS कोड की तरह ही काम करता है.

  1. android/app/res/layout/news_widget.xml फ़ाइल खोलें. इसमें आपकी होम स्क्रीन के विजेट के यूज़र इंटरफ़ेस (यूआई) एलिमेंट होते हैं. इसके कॉन्टेंट की जगह यह कोड डालें:

android/app/res/layout/news_widget.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
   android:id="@+id/widget_container"
   style="@style/Widget.Android.AppWidget.Container"
   android:layout_width="wrap_content"
   android:layout_height="match_parent"
   android:background="@android:color/white"
   android:theme="@style/Theme.Android.AppWidgetContainer">

   <TextView
       android:id="@+id/headline_title"
       style="@style/Widget.Android.AppWidget.InnerView"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignParentStart="true"
       android:layout_alignParentLeft="true"
       android:layout_marginStart="8dp"
       android:layout_marginLeft="8dp"
       android:background="@android:color/white"
       android:text="Title"
       android:textSize="20sp"
       android:textStyle="bold" />

   <TextView
       android:id="@+id/headline_description"
       style="@style/Widget.Android.AppWidget.InnerView"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_below="@+id/headline_title"
       android:layout_alignParentStart="true"
       android:layout_alignParentLeft="true"
       android:layout_marginStart="8dp"
       android:layout_marginLeft="8dp"
       android:layout_marginTop="4dp"
       android:background="@android:color/white"
       android:text="Title"
       android:textSize="16sp" />
   
   <!--New: add this image view -->
   <ImageView
       android:id="@+id/widget_image"
       android:layout_width="200dp"
       android:layout_height="200dp"
       android:layout_below="@+id/headline_description"
       android:layout_alignBottom="@+id/headline_title"
       android:layout_alignParentStart="true"
       android:layout_alignParentLeft="true"
       android:layout_marginStart="8dp"
       android:layout_marginLeft="8dp"
       android:layout_marginTop="6dp"
       android:layout_marginBottom="-134dp"
       android:layout_weight="1"
       android:adjustViewBounds="true"
       android:background="@android:color/white"
       android:scaleType="fitCenter"
       android:src="@android:drawable/star_big_on"
       android:visibility="visible"
       tools:visibility="visible" />

</RelativeLayout>

इस नए कोड से, होम स्क्रीन विजेट में एक इमेज जुड़ जाती है. फ़िलहाल, यह एक सामान्य स्टार आइकॉन दिखाता है. इस स्टार आइकॉन की जगह, Dart कोड में सेव की गई इमेज का इस्तेमाल करें.

  1. NewsWidget.kt फ़ाइल खोलें. इसके कॉन्टेंट की जगह यह कोड डालें:

android/app/java/com.mydomain.homescreen_widgets/NewsWidget.kt

// Import will depend on App ID.
package com.mydomain.homescreen_widgets

import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.widget.RemoteViews
import java.io.File
import es.antonborri.home_widget.HomeWidgetPlugin


/**
 * Implementation of App Widget functionality.
 */
class NewsWidget : AppWidgetProvider() {
    override fun onUpdate(
            context: Context,
            appWidgetManager: AppWidgetManager,
            appWidgetIds: IntArray,
    ) {
        for (appWidgetId in appWidgetIds) {
            val widgetData = HomeWidgetPlugin.getData(context)
            val views = RemoteViews(context.packageName, R.layout.news_widget).apply {

                val title = widgetData.getString("headline_title", null)
                setTextViewText(R.id.headline_title, title ?: "No title set")

                val description = widgetData.getString("headline_description", null)
                setTextViewText(R.id.headline_description, description ?: "No description set")

                // New: Add the section below
               // Get chart image and put it in the widget, if it exists
                val imageName = widgetData.getString("filename", null)
                val imageFile = File(imageName)
                val imageExists = imageFile.exists()
                if (imageExists) {
                    val myBitmap: Bitmap = BitmapFactory.decodeFile(imageFile.absolutePath)
                    setImageViewBitmap(R.id.widget_image, myBitmap)
                } else {
                    println("image not found!, looked @: ${imageName}")
                }
                // End new code
            }

            appWidgetManager.updateAppWidget(appWidgetId, views)
        }
    }
}

यह Dart कोड, filename कुंजी का इस्तेमाल करके, स्क्रीनशॉट को लोकल स्टोरेज में सेव करता है. यह इमेज का पूरा पाथ भी पाता है और उससे एक File ऑब्जेक्ट बनाता है. अगर इमेज मौजूद है, तो डार्ट कोड, होम स्क्रीन विजेट में मौजूद इमेज को नई इमेज से बदल देता है.

  1. ऐप्लिकेशन को फिर से लोड करें और लेख वाली स्क्रीन पर जाएं. होम स्क्रीन अपडेट करें दबाएं. होम स्क्रीन विजेट में चार्ट दिखता है.

7. अगले चरण

बधाई हो!

बधाई हो, आपने अपने Flutter iOS और Android ऐप्लिकेशन के लिए होम स्क्रीन विजेट बना लिए हैं!

अपने Flutter ऐप्लिकेशन में मौजूद कॉन्टेंट से लिंक करना

उपयोगकर्ता के क्लिक करने की जगह के हिसाब से, उसे अपने ऐप्लिकेशन के किसी पेज पर भेजा जा सकता है. उदाहरण के लिए, इस कोडलैब के समाचार ऐप्लिकेशन में, हो सकता है कि आपको उपयोगकर्ता को दिखाई गई हेडलाइन के लिए समाचार लेख दिखाना हो.

यह सुविधा, इस कोडलैब के दायरे से बाहर है. होम स्क्रीन विजेट से ऐप्लिकेशन लॉन्च करने का पता लगाने और यूआरएल के ज़रिए होम स्क्रीन विजेट से मैसेज भेजने के लिए, home_widget पैकेज से मिलने वाली स्ट्रीम का इस्तेमाल करने के उदाहरण देखें. ज़्यादा जानने के लिए, docs.flutter.dev पर डीप लिंकिंग से जुड़ा दस्तावेज़ देखें.

बैकग्राउंड में विजेट अपडेट करना

इस कोडलैब में, आपने बटन का इस्तेमाल करके होम स्क्रीन विजेट को अपडेट किया. हालांकि, टेस्टिंग के लिए यह तरीका सही है, लेकिन प्रोडक्शन कोड में आपको अपने ऐप्लिकेशन को बैकग्राउंड में होम स्क्रीन विजेट को अपडेट करने की अनुमति देनी पड़ सकती है. workmanager प्लगिन का इस्तेमाल करके, बैकग्राउंड टास्क बनाए जा सकते हैं. इससे होम स्क्रीन विजेट के लिए ज़रूरी संसाधनों को अपडेट किया जा सकता है. ज़्यादा जानने के लिए, home_widget पैकेज में बैकग्राउंड अपडेट सेक्शन देखें.

iOS के लिए, होम स्क्रीन विजेट को यूज़र इंटरफ़ेस (यूआई) अपडेट करने के लिए नेटवर्क अनुरोध करने की अनुमति भी दी जा सकती है. उस अनुरोध की शर्तों या फ़्रीक्वेंसी को कंट्रोल करने के लिए, टाइमलाइन का इस्तेमाल करें. टाइमलाइन का इस्तेमाल करने के बारे में ज़्यादा जानने के लिए, Apple का "विजेट को अप-टू-डेट रखना" दस्तावेज़ पढ़ें.

इस बारे में और पढ़ें