1. ভূমিকা
শেষ আপডেট: 2021-10-19
WebView Flutter প্লাগইন দিয়ে আপনি আপনার Android বা iOS Flutter অ্যাপে একটি WebView উইজেট যোগ করতে পারেন। iOS-এ WebView উইজেট একটি WKWebView দ্বারা ব্যাক করা হয়, যখন Android-এ WebView উইজেট একটি WebView দ্বারা ব্যাক করা হয়। প্লাগইনটি ওয়েব ভিউতে ফ্লটার উইজেট রেন্ডার করতে পারে। সুতরাং উদাহরণস্বরূপ ওয়েব ভিউতে একটি ড্রপ ডাউন মেনু রেন্ডার করা সম্ভব।
আপনি কি নির্মাণ করবেন
এই কোডল্যাবে, আপনি ফ্লটার SDK ব্যবহার করে একটি ওয়েবভিউ সমন্বিত করে ধাপে ধাপে একটি মোবাইল অ্যাপ তৈরি করবেন। আপনার অ্যাপ হবে:
- একটি
WebView
এ ওয়েব সামগ্রী প্রদর্শন করুন -
WebView
স্তুপীকৃত ফ্লটার উইজেটগুলি প্রদর্শন করুন৷ - পৃষ্ঠা লোড অগ্রগতি ইভেন্টে প্রতিক্রিয়া
-
WebViewController
এর মাধ্যমেWebView
নিয়ন্ত্রণ করুন -
NavigationDelegate
ব্যবহার করে ওয়েবসাইট ব্লক করুন - জাভাস্ক্রিপ্ট এক্সপ্রেশন মূল্যায়ন
-
JavascriptChannels
সাহায্যে জাভাস্ক্রিপ্ট থেকে কলব্যাক পরিচালনা করুন - কুকি সেট করুন, সরান, যোগ করুন বা দেখান
- এইচটিএমএল ধারণকারী সম্পদ, ফাইল বা স্ট্রিং থেকে এইচটিএমএল লোড এবং প্রদর্শন করুন
আপনি কি শিখবেন
এই কোডল্যাবে আপনি webview_flutter
প্লাগইনটি বিভিন্ন উপায়ে ব্যবহার করতে শিখবেন, যার মধ্যে রয়েছে:
- কিভাবে
webview_flutter
প্লাগইন কনফিগার করবেন - পৃষ্ঠা লোড অগ্রগতির ইভেন্টগুলির জন্য কীভাবে শুনবেন
- কিভাবে পৃষ্ঠা নেভিগেশন নিয়ন্ত্রণ করতে হয়
-
WebView
কীভাবে তার ইতিহাসের মধ্য দিয়ে পিছনের দিকে এবং এগিয়ে যাওয়ার নির্দেশ দেওয়া যায় - কিভাবে জাভাস্ক্রিপ্ট মূল্যায়ন করতে হয়, প্রত্যাবর্তিত ফলাফল ব্যবহার সহ
- জাভাস্ক্রিপ্ট থেকে ডার্ট কোড কল করতে কলব্যাকগুলি কীভাবে নিবন্ধন করবেন
- কুকিজ কিভাবে পরিচালনা করবেন
- সম্পদ বা ফাইল বা এইচটিএমএল ধারণকারী স্ট্রিং থেকে এইচটিএমএল পৃষ্ঠাগুলি কীভাবে লোড এবং প্রদর্শন করবেন
আপনি কি প্রয়োজন হবে
- অ্যান্ড্রয়েড স্টুডিও 4.1 বা তার পরে (অ্যান্ড্রয়েড বিকাশের জন্য)
- Xcode 12 বা তার পরে (iOS বিকাশের জন্য)
- ফ্লটার SDK
- একটি কোড এডিটর, যেমন Android স্টুডিও , ভিজ্যুয়াল স্টুডিও কোড , বা Emacs ।
2. আপনার ফ্লটার ডেভেলপমেন্ট এনভায়রনমেন্ট সেট আপ করুন
এই ল্যাবটি সম্পূর্ণ করার জন্য আপনার দুটি টুকরো সফ্টওয়্যার প্রয়োজন - ফ্লাটার SDK এবং একটি সম্পাদক ৷
আপনি এই ডিভাইসগুলির যেকোনো একটি ব্যবহার করে কোডল্যাব চালাতে পারেন:
- আপনার কম্পিউটারের সাথে সংযুক্ত এবং বিকাশকারী মোডে সেট করা একটি শারীরিক Android বা iOS ডিভাইস৷
- আইওএস সিমুলেটর (এক্সকোড সরঞ্জাম ইনস্টল করা প্রয়োজন)।
- অ্যান্ড্রয়েড এমুলেটর (অ্যান্ড্রয়েড স্টুডিওতে সেটআপ প্রয়োজন)।
3. শুরু করা
Flutter দিয়ে শুরু করা
অ্যান্ড্রয়েড স্টুডিও এবং ভিজ্যুয়াল স্টুডিও কোড উভয়ই এই কাজের জন্য টুলিং প্রদান করে একটি নতুন ফ্লাটার প্রকল্প তৈরি করার বিভিন্ন উপায় রয়েছে। একটি প্রকল্প তৈরি করতে লিঙ্কযুক্ত পদ্ধতিগুলি অনুসরণ করুন, অথবা একটি সহজ কমান্ড লাইন টার্মিনালে নিম্নলিখিত কমান্ডগুলি চালান।
$ flutter create --platforms=android,ios webview_in_flutter Creating project webview_in_flutter... Resolving dependencies in `webview_in_flutter`... Downloading packages... Got dependencies in `webview_in_flutter`. Wrote 74 files. All done! You can find general documentation for Flutter at: https://docs.flutter.dev/ Detailed API documentation is available at: https://api.flutter.dev/ If you prefer video documentation, consider: https://www.youtube.com/c/flutterdev In order to run your application, type: $ cd webview_in_flutter $ flutter run Your application code is in webview_in_flutter/lib/main.dart.
নির্ভরতা হিসাবে WebView Flutter প্লাগইন যোগ করা হচ্ছে
Pub প্যাকেজ ব্যবহার করে একটি Flutter অ্যাপে অতিরিক্ত ক্ষমতা যোগ করা সহজ। এই কোডল্যাবে আপনি আপনার প্রোজেক্টে webview_flutter
প্লাগইন যোগ করবেন। টার্মিনালে নিম্নলিখিত কমান্ডগুলি চালান।
$ cd webview_in_flutter $ flutter pub add webview_flutter Resolving dependencies... Downloading packages... collection 1.18.0 (1.19.0 available) leak_tracker 10.0.5 (10.0.7 available) leak_tracker_flutter_testing 3.0.5 (3.0.7 available) material_color_utilities 0.11.1 (0.12.0 available) + plugin_platform_interface 2.1.8 string_scanner 1.2.0 (1.3.0 available) test_api 0.7.2 (0.7.3 available) + webview_flutter 4.9.0 + webview_flutter_android 3.16.7 + webview_flutter_platform_interface 2.10.0 + webview_flutter_wkwebview 3.15.0 Changed 5 dependencies! 6 packages have newer versions incompatible with dependency constraints. Try `flutter pub outdated` for more information.
আপনি যদি আপনার pubspec.yaml পরিদর্শন করেন, তাহলে আপনি এখন দেখতে পাবেন এটির webview_flutter
প্লাগইনের জন্য নির্ভরতা বিভাগে একটি লাইন রয়েছে।
Android minSDK কনফিগার করুন
অ্যান্ড্রয়েডে webview_flutter
প্লাগইন ব্যবহার করতে আপনাকে minSDK
20
সেট করতে হবে। আপনার android/app/build.gradle
ফাইলটি নিম্নরূপ পরিবর্তন করুন:
android/app/build.gradle
android {
//...
defaultConfig {
applicationId = "com.example.webview_in_flutter"
minSdk = 20 // Modify this line
targetSdk = flutter.targetSdkVersion
versionCode = flutterVersionCode.toInteger()
versionName = flutterVersionName
}
4. Flutter অ্যাপে WebView উইজেট যোগ করা
এই ধাপে আপনি আপনার অ্যাপ্লিকেশনে একটি WebView
যোগ করবেন। ওয়েবভিউগুলি নেটিভ ভিউগুলি হোস্ট করা হয় এবং একজন অ্যাপ ডেভেলপার হিসাবে আপনার অ্যাপে এই নেটিভ ভিউগুলি কীভাবে হোস্ট করা যায় সে সম্পর্কে আপনার একটি পছন্দ রয়েছে৷ অ্যান্ড্রয়েডে আপনার ভার্চুয়াল ডিসপ্লে, বর্তমানে অ্যান্ড্রয়েডের জন্য ডিফল্ট এবং হাইব্রিড কম্পোজিশনের মধ্যে একটি পছন্দ আছে। যাইহোক, iOS সর্বদা হাইব্রিড রচনা ব্যবহার করে।
ভার্চুয়াল ডিসপ্লে এবং হাইব্রিড কম্পোজিশনের মধ্যে পার্থক্য সম্পর্কে গভীরভাবে আলোচনার জন্য, অনুগ্রহ করে প্ল্যাটফর্ম ভিউ সহ আপনার ফ্লাটার অ্যাপে নেটিভ অ্যান্ড্রয়েড এবং iOS ভিউ হোস্ট করার ডকুমেন্টেশনটি পড়ুন।
পর্দায় একটি ওয়েবভিউ রাখা
lib/main.dart
এর বিষয়বস্তুকে নিম্নলিখিত দিয়ে প্রতিস্থাপন করুন:
lib/main.dart
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
void main() {
runApp(
MaterialApp(
theme: ThemeData(useMaterial3: true),
home: const WebViewApp(),
),
);
}
class WebViewApp extends StatefulWidget {
const WebViewApp({super.key});
@override
State<WebViewApp> createState() => _WebViewAppState();
}
class _WebViewAppState extends State<WebViewApp> {
late final WebViewController controller;
@override
void initState() {
super.initState();
controller = WebViewController()
..loadRequest(
Uri.parse('https://flutter.dev'),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter WebView'),
),
body: WebViewWidget(
controller: controller,
),
);
}
}
iOS বা Android-এ এটি চালানোর ফলে আপনার ডিভাইসে একটি সম্পূর্ণ ব্লিড ব্রাউজার উইন্ডো হিসাবে একটি WebView দেখাবে, যার মানে হল যে ব্রাউজারটি আপনার ডিভাইসে কোনো সীমানা বা মার্জিন ছাড়াই ফুলস্ক্রিনে দেখানো হয়েছে। আপনি স্ক্রোল করার সময়, আপনি পৃষ্ঠার কিছু অংশ লক্ষ্য করবেন যেগুলি কিছুটা অদ্ভুত দেখাতে পারে। কারণ জাভাস্ক্রিপ্ট বর্তমানে অক্ষম এবং flutter.dev রেন্ডার করার জন্য সঠিকভাবে JavaScript প্রয়োজন।
অ্যাপটি চালানো হচ্ছে
একটি ওয়েবভিউ দেখতে iOS বা Android-এ Flutter অ্যাপ চালান, যা flutter.dev ওয়েবসাইট দেখায়। বিকল্পভাবে একটি Android এমুলেটর বা একটি iOS সিমুলেটরে অ্যাপটি চালান। প্রারম্ভিক WebView ইউআরএল প্রতিস্থাপন করতে নির্দ্বিধায় উদাহরণস্বরূপ আপনার নিজের ওয়েবসাইট.
$ flutter run
আপনার ডিভাইসে অ্যাপটি কম্পাইল এবং স্থাপন করার পরে আপনার কাছে উপযুক্ত সিমুলেটর বা এমুলেটর চলছে, বা একটি ফিজিক্যাল ডিভাইস সংযুক্ত আছে বলে ধরে নিলে, আপনি নিম্নলিখিতগুলির মতো কিছু দেখতে পাবেন:
5. পৃষ্ঠা লোড ইভেন্টের জন্য শোনা
WebView
উইজেট বেশ কিছু পৃষ্ঠা লোড অগ্রগতি ইভেন্ট প্রদান করে, যা আপনার অ্যাপ শুনতে পারে। WebView
পৃষ্ঠা লোড চক্রের সময় তিনটি ভিন্ন পৃষ্ঠা লোড ইভেন্ট রয়েছে যা ফায়ার করা হয়: onPageStarted
, onProgress
এবং onPageFinished
। এই ধাপে আপনি একটি পৃষ্ঠা লোড নির্দেশক প্রয়োগ করবেন। বোনাস হিসাবে, এটি দেখাবে যে আপনি WebView
বিষয়বস্তু এলাকায় ফ্লাটার সামগ্রী রেন্ডার করতে পারেন।
আপনার অ্যাপে পৃষ্ঠা লোড ইভেন্ট যোগ করা হচ্ছে
lib/src/web_view_stack.dart
এ একটি নতুন সোর্স ফাইল তৈরি করুন এবং নিম্নলিখিত বিষয়বস্তু দিয়ে এটি পূরণ করুন:
lib/src/web_view_stack.dart
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
class WebViewStack extends StatefulWidget {
const WebViewStack({super.key});
@override
State<WebViewStack> createState() => _WebViewStackState();
}
class _WebViewStackState extends State<WebViewStack> {
var loadingPercentage = 0;
late final WebViewController controller;
@override
void initState() {
super.initState();
controller = WebViewController()
..setNavigationDelegate(NavigationDelegate(
onPageStarted: (url) {
setState(() {
loadingPercentage = 0;
});
},
onProgress: (progress) {
setState(() {
loadingPercentage = progress;
});
},
onPageFinished: (url) {
setState(() {
loadingPercentage = 100;
});
},
))
..loadRequest(
Uri.parse('https://flutter.dev'),
);
}
@override
Widget build(BuildContext context) {
return Stack(
children: [
WebViewWidget(
controller: controller,
),
if (loadingPercentage < 100)
LinearProgressIndicator(
value: loadingPercentage / 100.0,
),
],
);
}
}
এই কোডটি WebView
উইজেটটিকে একটি Stack
মধ্যে আবৃত করেছে, যখন পৃষ্ঠা লোড শতাংশ 100% এর কম হয় তখন শর্তসাপেক্ষে একটি LinearProgressIndicator
দিয়ে WebView
ওভারলে করে৷ যেহেতু এটি সময়ের সাথে সাথে পরিবর্তিত হওয়া প্রোগ্রামের অবস্থার সাথে জড়িত, তাই আপনি একটি StatefulWidget
এর সাথে যুক্ত একটি State
শ্রেণিতে এই অবস্থাটি সংরক্ষণ করেছেন।
এই নতুন WebViewStack
উইজেটটি ব্যবহার করতে, আপনার lib/main.dart
নিম্নরূপ পরিবর্তন করুন:
lib/main.dart
import 'package:flutter/material.dart';
import 'src/web_view_stack.dart';
void main() {
runApp(
MaterialApp(
theme: ThemeData(useMaterial3: true),
home: const WebViewApp(),
),
);
}
class WebViewApp extends StatefulWidget {
const WebViewApp({super.key});
@override
State<WebViewApp> createState() => _WebViewAppState();
}
class _WebViewAppState extends State<WebViewApp> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter WebView'),
),
body: const WebViewStack(),
);
}
}
আপনি যখন অ্যাপটি চালান, আপনার নেটওয়ার্কের অবস্থার উপর নির্ভর করে এবং আপনি যে পৃষ্ঠাটিতে নেভিগেট করছেন ব্রাউজারটি ক্যাশে করেছে কিনা, আপনি WebView
বিষয়বস্তু এলাকার উপরে একটি পৃষ্ঠা লোডিং সূচক দেখতে পাবেন।
6. WebViewController এর সাথে কাজ করা
WebView Widget থেকে WebViewController অ্যাক্সেস করা
WebView
উইজেট একটি WebViewController
এর সাথে প্রোগ্রাম্যাটিক নিয়ন্ত্রণ সক্ষম করে। এই নিয়ামকটি একটি কলব্যাকের মাধ্যমে WebView
উইজেট নির্মাণের পরে উপলব্ধ করা হয়৷ এই কন্ট্রোলারের প্রাপ্যতার অ্যাসিঙ্ক্রোনাস প্রকৃতি এটিকে ডার্টের অ্যাসিঙ্ক্রোনাস Completer<T>
ক্লাসের প্রধান প্রার্থী করে তোলে।
নিম্নরূপ lib/src/web_view_stack.dart
আপডেট করুন:
lib/src/web_view_stack.dart
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
class WebViewStack extends StatefulWidget {
const WebViewStack({required this.controller, super.key}); // MODIFY
final WebViewController controller; // ADD
@override
State<WebViewStack> createState() => _WebViewStackState();
}
class _WebViewStackState extends State<WebViewStack> {
var loadingPercentage = 0;
// REMOVE the controller that was here
@override
void initState() {
super.initState();
// Modify from here...
widget.controller.setNavigationDelegate(
NavigationDelegate(
onPageStarted: (url) {
setState(() {
loadingPercentage = 0;
});
},
onProgress: (progress) {
setState(() {
loadingPercentage = progress;
});
},
onPageFinished: (url) {
setState(() {
loadingPercentage = 100;
});
},
),
);
// ...to here.
}
@override
Widget build(BuildContext context) {
return Stack(
children: [
WebViewWidget(
controller: widget.controller, // MODIFY
),
if (loadingPercentage < 100)
LinearProgressIndicator(
value: loadingPercentage / 100.0,
),
],
);
}
}
WebViewStack
উইজেট এখন আশেপাশের উইজেটে তৈরি একটি কন্ট্রোলার ব্যবহার করে। এটি WebViewWidget
এর কন্ট্রোলারকে অ্যাপের অন্যান্য অংশের সাথে সহজেই শেয়ার করতে সক্ষম করবে।
ন্যাভিগেশন কন্ট্রোল তৈরি করা
একটি কার্যকরী WebView
থাকা একটি জিনিস, কিন্তু পৃষ্ঠার ইতিহাসের মাধ্যমে পিছনে এবং সামনে নেভিগেট করতে সক্ষম হওয়া এবং পৃষ্ঠাটি পুনরায় লোড করা, সংযোজনের একটি দরকারী সেট হবে। সৌভাগ্যক্রমে, একটি WebViewController
দিয়ে আপনি আপনার অ্যাপে এই কার্যকারিতা যোগ করতে পারেন।
lib/src/navigation_controls.dart
এ একটি নতুন সোর্স ফাইল তৈরি করুন এবং নিম্নলিখিতগুলি দিয়ে এটি পূরণ করুন:
lib/src/navigation_controls.dart
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
class NavigationControls extends StatelessWidget {
const NavigationControls({required this.controller, super.key});
final WebViewController controller;
@override
Widget build(BuildContext context) {
return Row(
children: <Widget>[
IconButton(
icon: const Icon(Icons.arrow_back_ios),
onPressed: () async {
final messenger = ScaffoldMessenger.of(context);
if (await controller.canGoBack()) {
await controller.goBack();
} else {
messenger.showSnackBar(
const SnackBar(content: Text('No back history item')),
);
return;
}
},
),
IconButton(
icon: const Icon(Icons.arrow_forward_ios),
onPressed: () async {
final messenger = ScaffoldMessenger.of(context);
if (await controller.canGoForward()) {
await controller.goForward();
} else {
messenger.showSnackBar(
const SnackBar(content: Text('No forward history item')),
);
return;
}
},
),
IconButton(
icon: const Icon(Icons.replay),
onPressed: () {
controller.reload();
},
),
],
);
}
}
এই উইজেটটি IconButton
s এর একটি সিরিজের মাধ্যমে ব্যবহারকারীকে WebView
নিয়ন্ত্রণ করতে সক্ষম করতে নির্মাণের সময় এটির সাথে ভাগ করা WebViewController
ব্যবহার করে।
অ্যাপবারে নেভিগেশন নিয়ন্ত্রণ যোগ করা হচ্ছে
আপডেট করা WebViewStack
, এবং সদ্য তৈরি করা NavigationControls
হাতে নিয়ে, এখন আপনার জন্য একটি আপডেট করা WebViewApp
এ সবকিছু একসাথে রাখার সময় এসেছে৷ এখানেই আমরা শেয়ার করা WebViewController
তৈরি করি। এই অ্যাপে উইজেট গাছের শীর্ষের কাছে WebViewApp
সহ, এই স্তরে এটি তৈরি করা বোধগম্য।
lib/main.dart
ফাইলটি নিম্নরূপ আপডেট করুন:
lib/main.dart
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart'; // ADD
import 'src/navigation_controls.dart'; // ADD
import 'src/web_view_stack.dart';
void main() {
runApp(
MaterialApp(
theme: ThemeData(useMaterial3: true),
home: const WebViewApp(),
),
);
}
class WebViewApp extends StatefulWidget {
const WebViewApp({super.key});
@override
State<WebViewApp> createState() => _WebViewAppState();
}
class _WebViewAppState extends State<WebViewApp> {
// Add from here...
late final WebViewController controller;
@override
void initState() {
super.initState();
controller = WebViewController()
..loadRequest(
Uri.parse('https://flutter.dev'),
);
}
// ...to here.
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter WebView'),
// Add from here...
actions: [
NavigationControls(controller: controller),
],
// ...to here.
),
body: WebViewStack(controller: controller), // MODIFY
);
}
}
অ্যাপ্লিকেশন চালানো নিয়ন্ত্রণ সহ একটি ওয়েব পৃষ্ঠা প্রকাশ করা উচিত:
7. ন্যাভিগেশন ডেলিগেটের সাথে নেভিগেশন ট্র্যাক রাখা
WebView
আপনার অ্যাপকে একটি NavigationDelegate,
যা আপনার অ্যাপটিকে WebView
উইজেটের পৃষ্ঠা নেভিগেশন ট্র্যাক ও নিয়ন্ত্রণ করতে সক্ষম করে। যখন WebView,
উদাহরণস্বরূপ যখন একজন ব্যবহারকারী একটি লিঙ্কে ক্লিক করেন, তখন NavigationDelegate
বলা হয়। NavigationDelegate
কলব্যাক WebView
নেভিগেশনের সাথে এগিয়ে যায় কিনা তা নিয়ন্ত্রণ করতে ব্যবহার করা যেতে পারে।
একটি কাস্টম নেভিগেশন ডেলিগেট নিবন্ধন করুন
এই ধাপে, আপনি YouTube.com- এ নেভিগেশন ব্লক করতে একটি NavigationDelegate
কলব্যাক নিবন্ধন করবেন। দ্রষ্টব্য, এই সরলীকৃত বাস্তবায়ন ইনলাইন ইউটিউব সামগ্রীকেও ব্লক করে, যা বিভিন্ন Flutter API ডকুমেন্টেশন পৃষ্ঠাগুলিতে প্রদর্শিত হয়।
নিম্নরূপ lib/src/web_view_stack.dart
আপডেট করুন:
lib/src/web_view_stack.dart
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
class WebViewStack extends StatefulWidget {
const WebViewStack({required this.controller, super.key});
final WebViewController controller;
@override
State<WebViewStack> createState() => _WebViewStackState();
}
class _WebViewStackState extends State<WebViewStack> {
var loadingPercentage = 0;
@override
void initState() {
super.initState();
widget.controller.setNavigationDelegate(
NavigationDelegate(
onPageStarted: (url) {
setState(() {
loadingPercentage = 0;
});
},
onProgress: (progress) {
setState(() {
loadingPercentage = progress;
});
},
onPageFinished: (url) {
setState(() {
loadingPercentage = 100;
});
},
// Add from here...
onNavigationRequest: (navigation) {
final host = Uri.parse(navigation.url).host;
if (host.contains('youtube.com')) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'Blocking navigation to $host',
),
),
);
return NavigationDecision.prevent;
}
return NavigationDecision.navigate;
},
// ...to here.
),
);
}
@override
Widget build(BuildContext context) {
return Stack(
children: [
WebViewWidget(
controller: widget.controller,
),
if (loadingPercentage < 100)
LinearProgressIndicator(
value: loadingPercentage / 100.0,
),
],
);
}
}
পরবর্তী ধাপে, আপনি WebViewController
ক্লাস ব্যবহার করে আপনার NavigationDelegate
পরীক্ষা করার জন্য একটি মেনু আইটেম যোগ করবেন। শুধুমাত্র YouTube.com-এ সম্পূর্ণ পৃষ্ঠা নেভিগেশন ব্লক করতে এবং এখনও API ডকুমেন্টেশনে ইনলাইন YouTube বিষয়বস্তুকে অনুমতি দেওয়ার জন্য কলব্যাকের যুক্তি বাড়ানোর জন্য এটি পাঠকের জন্য একটি অনুশীলন হিসাবে ছেড়ে দেওয়া হয়েছে।
8. অ্যাপবারে একটি মেনু বোতাম যুক্ত করা হচ্ছে
পরবর্তী কয়েকটি ধাপে, আপনি AppBar
উইজেটে একটি মেনু বোতাম তৈরি করবেন যা জাভাস্ক্রিপ্ট মূল্যায়ন করতে, জাভাস্ক্রিপ্ট চ্যানেল চালু করতে এবং কুকি পরিচালনা করতে ব্যবহৃত হয়। সব মিলিয়ে, সত্যিই একটি দরকারী মেনু.
lib/src/menu.dart
এ একটি নতুন সোর্স ফাইল তৈরি করুন এবং নিম্নলিখিতগুলি দিয়ে এটি পূরণ করুন:
lib/src/menu.dart
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
enum _MenuOptions {
navigationDelegate,
}
class Menu extends StatelessWidget {
const Menu({required this.controller, super.key});
final WebViewController controller;
@override
Widget build(BuildContext context) {
return PopupMenuButton<_MenuOptions>(
onSelected: (value) async {
switch (value) {
case _MenuOptions.navigationDelegate:
await controller.loadRequest(Uri.parse('https://youtube.com'));
}
},
itemBuilder: (context) => [
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.navigationDelegate,
child: Text('Navigate to YouTube'),
),
],
);
}
}
ব্যবহারকারী যখন YouTube মেনুতে নেভিগেট বিকল্পটি নির্বাচন করেন, তখন WebViewController
এর loadRequest
পদ্ধতিটি কার্যকর করা হয়। এই নেভিগেশনটি আপনার আগের ধাপে তৈরি করা navigationDelegate
কলব্যাক দ্বারা অবরুদ্ধ করা হবে।
WebViewApp
এর স্ক্রিনে মেনু যোগ করতে, lib/main.dart
নিম্নরূপ পরিবর্তন করুন:
lib/main.dart
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'src/menu.dart'; // ADD
import 'src/navigation_controls.dart';
import 'src/web_view_stack.dart';
void main() {
runApp(
MaterialApp(
theme: ThemeData(useMaterial3: true),
home: const WebViewApp(),
),
);
}
class WebViewApp extends StatefulWidget {
const WebViewApp({super.key});
@override
State<WebViewApp> createState() => _WebViewAppState();
}
class _WebViewAppState extends State<WebViewApp> {
late final WebViewController controller;
@override
void initState() {
super.initState();
controller = WebViewController()
..loadRequest(
Uri.parse('https://flutter.dev'),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter WebView'),
actions: [
NavigationControls(controller: controller),
Menu(controller: controller), // ADD
],
),
body: WebViewStack(controller: controller),
);
}
}
আপনার অ্যাপটি চালান এবং YouTube মেনু আইটেমে নেভিগেট করুন। নেভিগেশন কন্ট্রোলার YouTube-এ নেভিগেট করা ব্লক করেছে তা জানিয়ে আপনাকে একটি SnackBar দিয়ে স্বাগত জানানো উচিত।
9. জাভাস্ক্রিপ্ট মূল্যায়ন
WebViewController
বর্তমান পৃষ্ঠার প্রসঙ্গে জাভাস্ক্রিপ্ট এক্সপ্রেশন মূল্যায়ন করতে পারে। জাভাস্ক্রিপ্ট মূল্যায়ন করার দুটি ভিন্ন উপায় রয়েছে: জাভাস্ক্রিপ্ট কোডের জন্য যা একটি মান ফেরত দেয় না, runJavaScript
ব্যবহার করুন, এবং জাভাস্ক্রিপ্ট কোডের জন্য যা একটি মান ফেরত দেয়, runJavaScriptReturningResult
ব্যবহার করুন।
JavaScript সক্ষম করতে, আপনাকে JavascriptMode.unrestricted
এ সেট করা javaScriptMode
সম্পত্তির সাথে WebViewController
কনফিগার করতে হবে। ডিফল্টরূপে, javascriptMode
JavascriptMode.disabled
এ সেট করা আছে।
নিম্নরূপ javascriptMode
সেটিং যোগ করে _WebViewStackState
ক্লাস আপডেট করুন:
lib/src/web_view_stack.dart
class _WebViewStackState extends State<WebViewStack> {
var loadingPercentage = 0;
@override
void initState() {
super.initState();
widget.controller
..setNavigationDelegate( // Modify this line to use .. instead of .
NavigationDelegate(
onPageStarted: (url) {
setState(() {
loadingPercentage = 0;
});
},
onProgress: (progress) {
setState(() {
loadingPercentage = progress;
});
},
onPageFinished: (url) {
setState(() {
loadingPercentage = 100;
});
},
onNavigationRequest: (navigation) {
final host = Uri.parse(navigation.url).host;
if (host.contains('youtube.com')) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'Blocking navigation to $host',
),
),
);
return NavigationDecision.prevent;
}
return NavigationDecision.navigate;
},
),
)
..setJavaScriptMode(JavaScriptMode.unrestricted); // Add this line
}
@override
Widget build(BuildContext context) {
return Stack(
children: [
WebViewWidget(
controller: widget.controller,
),
if (loadingPercentage < 100)
LinearProgressIndicator(
value: loadingPercentage / 100.0,
),
],
);
}
}
এখন যেহেতু WebViewWidget
JavaScript চালাতে পারে, আপনি runJavaScriptReturningResult
পদ্ধতি ব্যবহার করতে মেনুতে একটি বিকল্প যোগ করতে পারেন।
আপনার এডিটর বা কিছু কীবোর্ড কাজ ব্যবহার করে, মেনু ক্লাসটিকে স্টেটফুল উইজেটে রূপান্তর করুন। নিম্নলিখিতগুলি মেলে lib/src/menu.dart
পরিবর্তন করুন:
lib/src/menu.dart
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
enum _MenuOptions {
navigationDelegate,
userAgent, // Add this line
}
class Menu extends StatefulWidget { // Convert to StatefulWidget
const Menu({required this.controller, super.key});
final WebViewController controller;
@override // Add from here
State<Menu> createState() => _MenuState();
}
class _MenuState extends State<Menu> { // To here.
@override
Widget build(BuildContext context) {
return PopupMenuButton<_MenuOptions>(
onSelected: (value) async {
switch (value) {
case _MenuOptions.navigationDelegate: // Modify from here
await widget.controller
.loadRequest(Uri.parse('https://youtube.com'));
case _MenuOptions.userAgent:
final userAgent = await widget.controller
.runJavaScriptReturningResult('navigator.userAgent');
if (!context.mounted) return;
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('$userAgent'),
)); // To here.
}
},
itemBuilder: (context) => [
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.navigationDelegate,
child: Text('Navigate to YouTube'),
),
const PopupMenuItem<_MenuOptions>( // Add from here
value: _MenuOptions.userAgent,
child: Text('Show user-agent'),
), // To here.
],
);
}
}
আপনি যখন 'ব্যবহারকারী-এজেন্ট দেখান' মেনু বিকল্পে ট্যাপ করেন, তখন জাভাস্ক্রিপ্ট এক্সপ্রেশন navigator.userAgent
চালানোর ফলাফল একটি Snackbar
দেখানো হয়। অ্যাপটি চালানোর সময়, আপনি লক্ষ্য করতে পারেন যে Flutter.dev পৃষ্ঠাটি অন্যরকম দেখাচ্ছে। এটি জাভাস্ক্রিপ্ট সক্ষম করে চালানোর ফলাফল।
10. জাভাস্ক্রিপ্ট চ্যানেলের সাথে কাজ করা
JavaScript চ্যানেলগুলি আপনার অ্যাপকে WebViewWidget
এর JavaScript প্রসঙ্গে কলব্যাক হ্যান্ডলারদের নিবন্ধন করতে সক্ষম করে যা অ্যাপের ডার্ট কোডে মানগুলিকে ফিরিয়ে আনার জন্য আহ্বান করা যেতে পারে। এই ধাপে আপনি একটি SnackBar
চ্যানেল নিবন্ধন করবেন যা একটি XMLHttpRequest
এর ফলাফলের সাথে কল করা হবে।
WebViewStack
ক্লাসটি নিম্নরূপ আপডেট করুন:
lib/src/web_view_stack.dart
class WebViewStack extends StatefulWidget {
const WebViewStack({required this.controller, super.key});
final WebViewController controller;
@override
State<WebViewStack> createState() => _WebViewStackState();
}
class _WebViewStackState extends State<WebViewStack> {
var loadingPercentage = 0;
@override
void initState() {
super.initState();
widget.controller
..setNavigationDelegate(
NavigationDelegate(
onPageStarted: (url) {
setState(() {
loadingPercentage = 0;
});
},
onProgress: (progress) {
setState(() {
loadingPercentage = progress;
});
},
onPageFinished: (url) {
setState(() {
loadingPercentage = 100;
});
},
onNavigationRequest: (navigation) {
final host = Uri.parse(navigation.url).host;
if (host.contains('youtube.com')) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'Blocking navigation to $host',
),
),
);
return NavigationDecision.prevent;
}
return NavigationDecision.navigate;
},
),
)
// Modify from here...
..setJavaScriptMode(JavaScriptMode.unrestricted)
..addJavaScriptChannel(
'SnackBar',
onMessageReceived: (message) {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text(message.message)));
},
);
// ...to here.
}
@override
Widget build(BuildContext context) {
return Stack(
children: [
WebViewWidget(
controller: widget.controller,
),
if (loadingPercentage < 100)
LinearProgressIndicator(
value: loadingPercentage / 100.0,
),
],
);
}
}
Set
প্রতিটি জাভাস্ক্রিপ্ট চ্যানেলের জন্য, একটি চ্যানেল অবজেক্ট জাভাস্ক্রিপ্ট প্রসঙ্গে একটি উইন্ডো বৈশিষ্ট্য হিসাবে উপলব্ধ করা হয় যার নাম জাভাস্ক্রিপ্ট চ্যানেল name
একই নামে। JavaScript প্রসঙ্গ থেকে এটি ব্যবহার করে জাভাস্ক্রিপ্ট চ্যানেলে একটি বার্তা পাঠানোর জন্য postMessage
কল করা জড়িত যা JavascriptChannel
এর onMessageReceived
কলব্যাক হ্যান্ডলারে পাস করা হয়।
উপরে যোগ করা জাভাস্ক্রিপ্ট চ্যানেল ব্যবহার করতে, অন্য একটি মেনু আইটেম যোগ করুন যা জাভাস্ক্রিপ্ট প্রসঙ্গে একটি XMLHttpRequest
কার্যকর করে এবং SnackBar
JavaScript চ্যানেল ব্যবহার করে ফলাফলগুলি ফেরত দেয়।
এখন যেহেতু WebViewWidget
আমাদের JavaScript চ্যানেলগুলি সম্পর্কে জানে ,
আপনি অ্যাপটিকে আরও প্রসারিত করতে একটি উদাহরণ যোগ করবেন। এটি করার জন্য, Menu
ক্লাসে একটি অতিরিক্ত PopupMenuItem
যোগ করুন এবং অতিরিক্ত কার্যকারিতা যোগ করুন।
javascriptChannel
গণনার মান যোগ করে অতিরিক্ত মেনু বিকল্পের সাথে _MenuOptions
আপডেট করুন এবং নিম্নলিখিতভাবে Menu
ক্লাসে একটি বাস্তবায়ন যোগ করুন:
lib/src/menu.dart
enum _MenuOptions {
navigationDelegate,
userAgent,
javascriptChannel, // Add this option
}
class Menu extends StatefulWidget {
const Menu({required this.controller, super.key});
final WebViewController controller;
@override
State<Menu> createState() => _MenuState();
}
class _MenuState extends State<Menu> {
@override
Widget build(BuildContext context) {
return PopupMenuButton<_MenuOptions>(
onSelected: (value) async {
switch (value) {
case _MenuOptions.navigationDelegate:
await widget.controller
.loadRequest(Uri.parse('https://youtube.com'));
case _MenuOptions.userAgent:
final userAgent = await widget.controller
.runJavaScriptReturningResult('navigator.userAgent');
if (!context.mounted) return;
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('$userAgent'),
));
case _MenuOptions.javascriptChannel: // Add from here
await widget.controller.runJavaScript('''
var req = new XMLHttpRequest();
req.open('GET', "https://api.ipify.org/?format=json");
req.onload = function() {
if (req.status == 200) {
let response = JSON.parse(req.responseText);
SnackBar.postMessage("IP Address: " + response.ip);
} else {
SnackBar.postMessage("Error: " + req.status);
}
}
req.send();'''); // To here.
}
},
itemBuilder: (context) => [
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.navigationDelegate,
child: Text('Navigate to YouTube'),
),
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.userAgent,
child: Text('Show user-agent'),
),
const PopupMenuItem<_MenuOptions>( // Add from here
value: _MenuOptions.javascriptChannel,
child: Text('Lookup IP Address'),
), // To here.
],
);
}
}
যখন ব্যবহারকারী JavaScript চ্যানেল উদাহরণ মেনু বিকল্পটি বেছে নেয় তখন এই জাভাস্ক্রিপ্টটি কার্যকর করা হয়।
var req = new XMLHttpRequest();
req.open('GET', "https://api.ipify.org/?format=json");
req.onload = function() {
if (req.status == 200) {
SnackBar.postMessage(req.responseText);
} else {
SnackBar.postMessage("Error: " + req.status);
}
}
req.send();
এই কোডটি একটি পাবলিক আইপি অ্যাড্রেস এপিআইতে একটি GET
অনুরোধ পাঠায়, ডিভাইসের আইপি অ্যাড্রেস ফিরিয়ে দেয়। এই ফলাফলটি SnackBar
JavascriptChannel
এ postMessage
দিয়ে SnackBar
দেখানো হয়েছে।
11. কুকিজ পরিচালনা
আপনার অ্যাপ CookieManager
ক্লাস ব্যবহার করে WebView
কুকি পরিচালনা করতে পারে। এই ধাপে, আপনি কুকিজের একটি তালিকা দেখাতে যাচ্ছেন, কুকিজের তালিকা সাফ করতে, কুকি মুছে ফেলতে এবং নতুন কুকি সেট করতে যাচ্ছেন। প্রতিটি কুকি ব্যবহারের ক্ষেত্রে নিম্নলিখিত _MenuOptions
এ এন্ট্রি যোগ করুন:
lib/src/menu.dart
enum _MenuOptions {
navigationDelegate,
userAgent,
javascriptChannel,
// Add from here ...
listCookies,
clearCookies,
addCookie,
setCookie,
removeCookie,
// ... to here.
}
এই ধাপের বাকি পরিবর্তনগুলি Menu
ক্লাসের উপর ফোকাস করা হয়েছে, যার মধ্যে Menu
ক্লাসকে স্টেটলেস থেকে স্টেটফুল এ রূপান্তর করা। এই পরিবর্তনটি গুরুত্বপূর্ণ কারণ Menu
CookieManager
মালিকানা থাকা প্রয়োজন, এবং স্টেটলেস উইজেটগুলিতে পরিবর্তনযোগ্য অবস্থা একটি খারাপ সমন্বয়।
কুকি ম্যানেজারকে ফলস্বরূপ স্টেট ক্লাসে নিম্নরূপ যোগ করুন:
lib/src/menu.dart
class Menu extends StatefulWidget {
const Menu({required this.controller, super.key});
final WebViewController controller;
@override
State<Menu> createState() => _MenuState();
}
class _MenuState extends State<Menu> {
final cookieManager = WebViewCookieManager(); // Add this line
@override
Widget build(BuildContext context) {
// ...
_MenuState
ক্লাসে Menu
ক্লাসে পূর্বে যোগ করা কোডটি থাকবে, সাথে নতুন যোগ করা CookieManager
। পরবর্তী ধারার বিভাগগুলিতে, আপনি _MenuState
এ সহায়ক ফাংশন যোগ করবেন যেগুলি, এখনও যোগ করা মেনু আইটেমগুলির দ্বারা আহ্বান করা হবে।
সব কুকিজ একটি তালিকা পান
আপনি সমস্ত কুকির তালিকা পেতে জাভাস্ক্রিপ্ট ব্যবহার করতে যাচ্ছেন। এটি অর্জন করতে, _MenuState
ক্লাসের শেষে একটি সহায়ক পদ্ধতি যোগ করুন, যাকে বলা হয় _onListCookies
। runJavaScriptReturningResult
পদ্ধতি ব্যবহার করে, আপনার সহায়ক পদ্ধতি জাভাস্ক্রিপ্ট প্রসঙ্গে document.cookie
চালায়, সমস্ত কুকির একটি তালিকা ফেরত দেয়।
_MenuState
ক্লাসে নিম্নলিখিত যোগ করুন:
lib/src/menu.dart
Future<void> _onListCookies(WebViewController controller) async {
final String cookies = await controller
.runJavaScriptReturningResult('document.cookie') as String;
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(cookies.isNotEmpty ? cookies : 'There are no cookies.'),
),
);
}
সমস্ত কুকিজ সাফ করুন
WebView-এর সমস্ত কুকিজ সাফ করতে, CookieManager
ক্লাসের clearCookies
পদ্ধতি ব্যবহার করুন। পদ্ধতিটি একটি Future<bool>
ফেরত দেয় যা CookieManager
কুকিজ সাফ করলে true
এবং সাফ করার জন্য কোন কুকি না থাকলে false
।
_MenuState
ক্লাসে নিম্নলিখিত যোগ করুন:
lib/src/menu.dart
Future<void> _onClearCookies() async {
final hadCookies = await cookieManager.clearCookies();
String message = 'There were cookies. Now, they are gone!';
if (!hadCookies) {
message = 'There were no cookies to clear.';
}
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(message),
),
);
}
একটি কুকি যোগ করুন
জাভাস্ক্রিপ্ট ব্যবহার করে কুকি যোগ করা যেতে পারে। একটি JavaScript নথিতে একটি কুকি যোগ করতে ব্যবহৃত API MDN-এ গভীরভাবে নথিভুক্ত করা হয়েছে।
_MenuState
ক্লাসে নিম্নলিখিত যোগ করুন:
lib/src/menu.dart
Future<void> _onAddCookie(WebViewController controller) async {
await controller.runJavaScript('''var date = new Date();
date.setTime(date.getTime()+(30*24*60*60*1000));
document.cookie = "FirstName=John; expires=" + date.toGMTString();''');
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Custom cookie added.'),
),
);
}
কুকি ম্যানেজার দিয়ে একটি কুকি সেট করা হচ্ছে
নিচের মত কুকি ম্যানেজার ব্যবহার করেও কুকি সেট করা যেতে পারে।
_MenuState
ক্লাসে নিম্নলিখিত যোগ করুন:
lib/src/menu.dart
Future<void> _onSetCookie(WebViewController controller) async {
await cookieManager.setCookie(
const WebViewCookie(name: 'foo', value: 'bar', domain: 'flutter.dev'),
);
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Custom cookie is set.'),
),
);
}
একটি কুকি সরান
একটি কুকি মুছে ফেলার সাথে একটি কুকি যোগ করা জড়িত, অতীতে একটি মেয়াদ শেষ হওয়ার তারিখ সেট করা।
_MenuState
ক্লাসে নিম্নলিখিত যোগ করুন:
lib/src/menu.dart
Future<void> _onRemoveCookie(WebViewController controller) async {
await controller.runJavaScript(
'document.cookie="FirstName=John; expires=Thu, 01 Jan 1970 00:00:00 UTC" ');
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Custom cookie removed.'),
),
);
}
কুকি ম্যানেজার মেনু আইটেম যোগ করা হচ্ছে
যা অবশিষ্ট থাকে তা হল মেনু বিকল্পগুলি যোগ করা এবং সেগুলিকে আপনি এইমাত্র যোগ করা সাহায্যকারী পদ্ধতিতে সংযুক্ত করুন৷ নিম্নরূপ _MenuState
ক্লাস আপডেট করুন:
lib/src/menu.dart
class _MenuState extends State<Menu> {
final cookieManager = WebViewCookieManager();
@override
Widget build(BuildContext context) {
return PopupMenuButton<_MenuOptions>(
onSelected: (value) async {
switch (value) {
case _MenuOptions.navigationDelegate:
await widget.controller
.loadRequest(Uri.parse('https://youtube.com'));
case _MenuOptions.userAgent:
final userAgent = await widget.controller
.runJavaScriptReturningResult('navigator.userAgent');
if (!context.mounted) return;
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('$userAgent'),
));
case _MenuOptions.javascriptChannel:
await widget.controller.runJavaScript('''
var req = new XMLHttpRequest();
req.open('GET', "https://api.ipify.org/?format=json");
req.onload = function() {
if (req.status == 200) {
let response = JSON.parse(req.responseText);
SnackBar.postMessage("IP Address: " + response.ip);
} else {
SnackBar.postMessage("Error: " + req.status);
}
}
req.send();''');
case _MenuOptions.clearCookies: // Add from here
await _onClearCookies();
case _MenuOptions.listCookies:
await _onListCookies(widget.controller);
case _MenuOptions.addCookie:
await _onAddCookie(widget.controller);
case _MenuOptions.setCookie:
await _onSetCookie(widget.controller);
case _MenuOptions.removeCookie:
await _onRemoveCookie(widget.controller); // To here.
}
},
itemBuilder: (context) => [
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.navigationDelegate,
child: Text('Navigate to YouTube'),
),
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.userAgent,
child: Text('Show user-agent'),
),
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.javascriptChannel,
child: Text('Lookup IP Address'),
),
const PopupMenuItem<_MenuOptions>( // Add from here
value: _MenuOptions.clearCookies,
child: Text('Clear cookies'),
),
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.listCookies,
child: Text('List cookies'),
),
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.addCookie,
child: Text('Add cookie'),
),
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.setCookie,
child: Text('Set cookie'),
),
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.removeCookie,
child: Text('Remove cookie'),
), // To here.
],
);
}
কুকি ম্যানেজার ব্যায়াম করা হচ্ছে
আপনি এইমাত্র অ্যাপে যোগ করেছেন এমন সমস্ত কার্যকারিতা ব্যবহার করতে, নিম্নলিখিত পদক্ষেপগুলি চেষ্টা করুন:
- তালিকা কুকিজ নির্বাচন করুন। এটি flutter.dev দ্বারা সেট করা Google Analytics কুকিগুলির তালিকা করা উচিত৷
- সাফ কুকিজ নির্বাচন করুন। এটি রিপোর্ট করা উচিত যে কুকিগুলি প্রকৃতপক্ষে সাফ করা হয়েছে৷
- আবার ক্লিয়ার কুকিজ নির্বাচন করুন। এটি রিপোর্ট করা উচিত যে সাফ করার জন্য কোন কুকিজ উপলব্ধ ছিল না।
- তালিকা কুকিজ নির্বাচন করুন। এটা কোন কুকি আছে যে রিপোর্ট করা উচিত.
- কুকি যোগ করুন নির্বাচন করুন। এটি যোগ করা হিসাবে কুকি রিপোর্ট করা উচিত.
- কুকি সেট করুন নির্বাচন করুন। এটা সেট হিসাবে কুকি রিপোর্ট করা উচিত.
- তালিকা কুকি নির্বাচন করুন, এবং তারপর একটি চূড়ান্ত উন্নতি হিসাবে, কুকি সরান নির্বাচন করুন।
12. WebView এ Flutter সম্পদ, ফাইল এবং HTML স্ট্রিং লোড করুন
আপনার অ্যাপ বিভিন্ন পদ্ধতি ব্যবহার করে HTML ফাইল লোড করতে পারে এবং সেগুলিকে WebView-এ প্রদর্শন করতে পারে। এই ধাপে আপনি pubspec.yaml
ফাইলে নির্দিষ্ট একটি Flutter সম্পদ লোড করবেন, নির্দিষ্ট পাথে অবস্থিত একটি ফাইল লোড করবেন এবং একটি HTML স্ট্রিং ব্যবহার করে একটি পৃষ্ঠা লোড করবেন।
আপনি যদি একটি নির্দিষ্ট পাথে অবস্থিত একটি ফাইল লোড করতে চান, তাহলে আপনাকে pubspec.yaml
এ path_provider
যোগ করতে হবে। এটি একটি ফ্লাটার প্লাগইন যা ফাইল সিস্টেমে সাধারণত ব্যবহৃত অবস্থানগুলি খুঁজে বের করার জন্য।
কমান্ড লাইনে, নিম্নলিখিত কমান্ডটি চালান:
$ flutter pub add path_provider
সম্পদ লোড করার জন্য আমাদের pubspec.yaml
এ সম্পদের পথ নির্দিষ্ট করতে হবে। pubspec.yaml
এ নিম্নলিখিত লাইনগুলি যোগ করুন:
pubspec.yaml
# The following section is specific to Flutter packages.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# Add from here
assets:
- assets/www/index.html
- assets/www/styles/style.css
# ... to here.
আপনার প্রকল্পে সম্পদ যোগ করতে, নিম্নলিখিত পদক্ষেপগুলি করুন:
- আপনার প্রকল্পের রুট ফোল্ডারে নাম
assets
সহ একটি নতুন ডিরেক্টরি তৈরি করুন। -
assets
ফোল্ডারেwww
নামের একটি নতুন ডিরেক্টরি তৈরি করুন। -
www
ফোল্ডারে নামেরstyles
সহ একটি নতুন ডিরেক্টরি তৈরি করুন। -
www
ফোল্ডারেindex.html
নামের একটি নতুন ফাইল তৈরি করুন। -
styles
ফোল্ডারেstyle.css
নামে একটি নতুন ফাইল তৈরি করুন।
index.html
ফাইলে নিম্নলিখিত কোডটি অনুলিপি করুন এবং পেস্ট করুন:
<!DOCTYPE html>
<!-- Copyright 2013 The Flutter Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<html lang="en">
<head>
<title>Load file or HTML string example</title>
<link rel="stylesheet" href="styles/style.css" />
</head>
<body>
<h1>Local demo page</h1>
<p>
This is an example page used to demonstrate how to load a local file or HTML
string using the <a href="https://pub.dev/packages/webview_flutter">Flutter
webview</a> plugin.
</p>
</body>
</html>
style.css-এর জন্য HTML হেডার স্টাইল সেট করতে নিম্নলিখিত কয়েকটি লাইন ব্যবহার করুন:
h1 {
color: blue;
}
এখন যেহেতু সম্পদগুলি সেট করা হয়েছে এবং ব্যবহারের জন্য প্রস্তুত, আপনি ফ্লাটার সম্পদ, ফাইল বা HTML স্ট্রিংগুলি লোড এবং প্রদর্শনের জন্য প্রয়োজনীয় পদ্ধতিগুলি প্রয়োগ করতে পারেন৷
লোড ফ্লাটার সম্পদ
আপনার তৈরি করা সম্পদ লোড করার জন্য, আপনাকে যা করতে হবে তা হল WebViewController
ব্যবহার করে loadFlutterAsset
পদ্ধতিতে কল করুন এবং প্যারামিটার হিসাবে সম্পদের পথ দিন। আপনার কোডের শেষে নিম্নলিখিত পদ্ধতি যোগ করুন:
lib/src/menu.dart
Future<void> _onLoadFlutterAssetExample(
WebViewController controller, BuildContext context) async {
await controller.loadFlutterAsset('assets/www/index.html');
}
স্থানীয় ফাইল লোড করুন
আপনার ডিভাইসে একটি ফাইল লোড করার জন্য আপনি একটি পদ্ধতি যোগ করতে পারেন যা loadFile
পদ্ধতি ব্যবহার করবে, আবার WebViewController
ব্যবহার করে যা ফাইলটির পাথ ধারণকারী একটি String
নেয়।
আপনাকে প্রথমে HTML কোড সম্বলিত একটি ফাইল তৈরি করতে হবে। আপনি কেবলমাত্র আমদানির নীচে menu.dart
ফাইলে আপনার কোডের শীর্ষে একটি স্ট্রিং হিসাবে HTML কোড যোগ করে এটি করতে পারেন।
import 'dart:io'; // Add this line,
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart'; // And this one.
import 'package:webview_flutter/webview_flutter.dart';
// Add from here ...
const String kExamplePage = '''
<!DOCTYPE html>
<html lang="en">
<head>
<title>Load file or HTML string example</title>
</head>
<body>
<h1>Local demo page</h1>
<p>
This is an example page used to demonstrate how to load a local file or HTML
string using the <a href="https://pub.dev/packages/webview_flutter">Flutter
webview</a> plugin.
</p>
</body>
</html>
''';
// ... to here.
একটি File
তৈরি করতে এবং ফাইলটিতে HTML স্ট্রিং লিখতে আপনি দুটি পদ্ধতি যুক্ত করবেন। _onLoadLocalFileExample
একটি স্ট্রিং হিসাবে পাথ প্রদান করে ফাইলটি লোড করবে যা _prepareLocalFile()
পদ্ধতি দ্বারা ফেরত দেওয়া হয়। আপনার কোডে নিম্নলিখিত পদ্ধতি যোগ করুন:
Future<void> _onLoadLocalFileExample(
WebViewController controller, BuildContext context) async {
final String pathToIndex = await _prepareLocalFile();
await controller.loadFile(pathToIndex);
}
static Future<String> _prepareLocalFile() async {
final String tmpDir = (await getTemporaryDirectory()).path;
final File indexFile = File('$tmpDir/www/index.html');
await Directory('$tmpDir/www').create(recursive: true);
await indexFile.writeAsString(kExamplePage);
return indexFile.path;
}
HTML স্ট্রিং লোড করুন
একটি HTML স্ট্রিং প্রদান করে একটি পৃষ্ঠা প্রদর্শন করা বেশ সোজা এগিয়ে. WebViewController
একটি পদ্ধতি রয়েছে যা আপনি loadHtmlString
নামে ব্যবহার করতে পারেন যেখানে আপনি একটি যুক্তি হিসাবে HTML স্ট্রিং দিতে পারেন। WebView
তারপর প্রদত্ত HTML পৃষ্ঠা প্রদর্শন করবে। আপনার কোডে নিম্নলিখিত পদ্ধতি যোগ করুন:
Future<void> _onLoadFlutterAssetExample(
WebViewController controller, BuildContext context) async {
await controller.loadFlutterAsset('assets/www/index.html');
}
Future<void> _onLoadLocalFileExample(
WebViewController controller, BuildContext context) async {
final String pathToIndex = await _prepareLocalFile();
await controller.loadFile(pathToIndex);
}
static Future<String> _prepareLocalFile() async {
final String tmpDir = (await getTemporaryDirectory()).path;
final File indexFile = File('$tmpDir/www/index.html');
await Directory('$tmpDir/www').create(recursive: true);
await indexFile.writeAsString(kExamplePage);
return indexFile.path;
}
// Add here ...
Future<void> _onLoadHtmlStringExample(
WebViewController controller, BuildContext context) async {
await controller.loadHtmlString(kExamplePage);
}
// ... to here.
মেনু আইটেম যোগ করুন
এখন যেহেতু সম্পদগুলি সেট করা হয়েছে এবং ব্যবহারের জন্য প্রস্তুত, এবং সমস্ত কার্যকারিতা সহ পদ্ধতিগুলি তৈরি করা হয়েছে, মেনু আপডেট করা যেতে পারে৷ _MenuOptions
enum-এ নিম্নলিখিত এন্ট্রি যোগ করুন:
lib/src/menu.dart
enum _MenuOptions {
navigationDelegate,
userAgent,
javascriptChannel,
listCookies,
clearCookies,
addCookie,
setCookie,
removeCookie,
// Add from here ...
loadFlutterAsset,
loadLocalFile,
loadHtmlString,
// ... to here.
}
এখন যে enum আপডেট করা হয়েছে আপনি মেনু বিকল্প যোগ করতে পারেন, এবং আপনি এইমাত্র যোগ করা সাহায্যকারী পদ্ধতিতে তাদের সংযুক্ত করতে পারেন। নিম্নরূপ _MenuState
ক্লাস আপডেট করুন:
lib/src/menu.dart
class _MenuState extends State<Menu> {
final cookieManager = WebViewCookieManager();
@override
Widget build(BuildContext context) {
return PopupMenuButton<_MenuOptions>(
onSelected: (value) async {
switch (value) {
case _MenuOptions.navigationDelegate:
await widget.controller
.loadRequest(Uri.parse('https://youtube.com'));
case _MenuOptions.userAgent:
final userAgent = await widget.controller
.runJavaScriptReturningResult('navigator.userAgent');
if (!context.mounted) return;
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('$userAgent'),
));
case _MenuOptions.javascriptChannel:
await widget.controller.runJavaScript('''
var req = new XMLHttpRequest();
req.open('GET', "https://api.ipify.org/?format=json");
req.onload = function() {
if (req.status == 200) {
let response = JSON.parse(req.responseText);
SnackBar.postMessage("IP Address: " + response.ip);
} else {
SnackBar.postMessage("Error: " + req.status);
}
}
req.send();''');
case _MenuOptions.clearCookies:
await _onClearCookies();
case _MenuOptions.listCookies:
await _onListCookies(widget.controller);
case _MenuOptions.addCookie:
await _onAddCookie(widget.controller);
case _MenuOptions.setCookie:
await _onSetCookie(widget.controller);
case _MenuOptions.removeCookie:
await _onRemoveCookie(widget.controller);
case _MenuOptions.loadFlutterAsset: // Add from here
if (!mounted) return;
await _onLoadFlutterAssetExample(widget.controller, context);
case _MenuOptions.loadLocalFile:
if (!mounted) return;
await _onLoadLocalFileExample(widget.controller, context);
case _MenuOptions.loadHtmlString:
if (!mounted) return;
await _onLoadHtmlStringExample(widget.controller, context);
// To here.
}
},
itemBuilder: (context) => [
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.navigationDelegate,
child: Text('Navigate to YouTube'),
),
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.userAgent,
child: Text('Show user-agent'),
),
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.javascriptChannel,
child: Text('Lookup IP Address'),
),
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.clearCookies,
child: Text('Clear cookies'),
),
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.listCookies,
child: Text('List cookies'),
),
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.addCookie,
child: Text('Add cookie'),
),
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.setCookie,
child: Text('Set cookie'),
),
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.removeCookie,
child: Text('Remove cookie'),
),
const PopupMenuItem<_MenuOptions>( // Add from here
value: _MenuOptions.loadFlutterAsset,
child: Text('Load Flutter Asset'),
),
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.loadHtmlString,
child: Text('Load HTML string'),
),
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.loadLocalFile,
child: Text('Load local file'),
), // To here.
],
);
}
সম্পদ, ফাইল এবং HTML স্ট্রিং পরীক্ষা করা হচ্ছে
আপনি এইমাত্র প্রয়োগ করা কোডটি কাজ করেছে কিনা তা পরীক্ষা করতে, আপনি আপনার ডিভাইসে কোডটি চালাতে পারেন এবং নতুন যোগ করা মেনু আইটেমগুলির একটিতে ক্লিক করতে পারেন। লক্ষ্য করুন কিভাবে _onLoadFlutterAssetExample
HTML ফাইলের হেডারটিকে নীল রঙে পরিবর্তন করতে আমাদের যোগ করা style.css
ব্যবহার করে।
13. সব সম্পন্ন!
অভিনন্দন!!! আপনি কোডল্যাব সম্পূর্ণ করেছেন। আপনি কোডল্যাব সংগ্রহস্থলে এই কোডল্যাবের জন্য সম্পূর্ণ কোডটি খুঁজে পেতে পারেন।
আরও জানতে, অন্যান্য ফ্লটার কোডল্যাব ব্যবহার করে দেখুন।