Flutter网页浏览插件deekweb的使用

Flutter网页浏览插件deekweb的使用

DeekWeb 是一个用于 Dart / Flutter 的强类型 REST 客户端。其目标是提供一种机制,以保持一致且强类型的网络请求框架。它使你能够清晰地分离应用程序逻辑与调用服务器并解析结果到类所需的逻辑。

DeekWebClient 与 json_serializable 框架一起使用时,可以很好地解析你的响应。

为什么使用 DeekWeb?

使用 Dart / Flutter 的主要优势之一在于其现代、强类型且支持空安全的特性。那么,你的网络访问是否也应该具备这些优点呢?

DeekWeb 让你可以预先定义一次合约,并在需要的地方使用它们,从而保持逻辑的清洁、安全和易读性。这里的方法很大程度上受到了 Android 中 Volley 的启发,但针对异步环境进行了现代化处理。

入门指南

首先,通过扩展 DeekWebRequest 来定义一个请求:

class MyRequest extends DeekWebRequest<MyResponseType> {
  [@override](/user/override)
  Method get method => Method.get;

  [@override](/user/override)
  Uri get uri => Uri.parse("https://www.myserver.com/myendpoint");

  [@override](/user/override)
  Map<String, String> get headers {
    return {
      "someHeader": "someValue"
    };
  }

  [@override](/user/override)
  Response<MyResponseType>? parseResponse(DeekWebHttpResponse response) {
    if (response.statusCode == 200) {
      var decoded = jsonDecode(response.body);
      return MyResponseType.fromJson(decoded);
    } else {
      return null;  
    }
  }      
}

然后,使用 DeekWebClient 执行请求:

Future<MyResponseType> getResponse() async {
  var request = MyRequest();  
  var client = DeekWebClient();
  var response = await client.executeRequest(request);
  return response;
}

高级功能

日志记录

你可以向 DeekWebClient 类传递一个日志类。客户端将在请求过程中记录各种事件和更改。原始请求/响应不会被记录。

class MyLogger implements DeekWebLogger {
  verbose(String logLine) => print(logline);
  info(String logLine) => print(logline);
  warn(String logLine) => print(logline);
  error(String logLine, {Exception? e}) => print("$logline: ${e ?? 'null'}");
}

void makeRequest() {
  var client = DeekWebClient(logger: MyLogger());
  /// 执行请求
}
相关向量

DeekWebClient 已经为每个请求生成了一个唯一的 ID。如果你想在请求头中包含该 ID,可以使用相关向量(Correlation Vectors)。这可以作为一个强大的调试工具,从客户端发送 ID 并通过系统中的日志跟踪请求。

如果你希望将请求 ID 包含在请求头中,可以在 DeekWebClient 构造函数中指定:

void makeRequest() {
  var client = DeekWebClient(includeCvHeader: true, cvHeader: 'My-CV');
  /// 执行请求
}
监听器

你可能发现知道正在进行哪些请求及其状态很有用。例如,当请求正在进行时,你的应用可能会显示同步指示器。你可以连接一个监听器到 DeekWebClient,它会在请求开始或完成时通知你:

class MyListener implements DeekWebListener {
  [@override](/user/override)
  void requestCompleted({required String requestId, required int statusCode}) {
    /// 当请求完成时执行某些操作
  }

  [@override](/user/override)
  void requestCompletedWithError(
      {required String requestId, int? statusCode, String? error}) {
    /// 当请求失败时执行某些操作
  }

  [@override](/user/override)
  void requestStarted(
      {required String requestId, required String requestType}) {
    /// 当请求开始时执行某些操作
  }
}

void makeRequest(MyListener requestListener) {
  var client = DeekWebClient(listener: requestListener);
  /// 执行请求
}

示例代码

以下是一个完整的示例,展示了如何使用 DeekWebClient 进行网络请求并解析响应。

import 'dart:convert';
import 'package:deekweb/deekweb.dart';
import 'package:flutter/material.dart';

void main() => runApp(const ExampleApp());

/// 示例应用,展示如何使用 `DeekWebClient` 发起请求并解析响应。
class ExampleApp extends StatelessWidget {
  const ExampleApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'DeekWeb Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const ExampleAppHomePage(),
    );
  }
}

class ExampleAppHomePage extends StatefulWidget {
  const ExampleAppHomePage({super.key});

  [@override](/user/override)
  State<StatefulWidget> createState() => _ExampleAppHomePageState();
}

/// 设置此小部件作为 `DeekWebClient` 状态变化的监听器
class _ExampleAppHomePageState extends State<ExampleAppHomePage> implements DeekWebListener {
  final DeekWebClient client = DeekWebClient();
  String status = "等待";
  String response = "";

  [@override](/user/override)
  void initState() {
    super.initState();

    // 将此小部件添加为 `DeekWebClient` 的监听器
    client.addListener(this);
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
            child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        ElevatedButton(
            onPressed: () => startRequest(),
            child: const Text('开始GET请求')),
        Text(status, style: const TextStyle(fontSize: 24)),
        Text(response, style: const TextStyle(fontSize: 16))
      ],
    )));
  }

  Future startRequest() async {
    setState(() => response = "");
    // 首先创建你的请求
    var request = ExampleRequest(latitude: 39.2741349, longitude: -74.5760937);

    // 使用客户端执行请求
    var result = await client.executeRequest(request);

    // 检查解析后的响应
    if (result.data != null) {
      response = "ID: ${result.data!.id}, Type: ${result.data!.type}";
    } else {
      response = "空响应";
    }
  }

  [@override](/user/override)
  void requestCompleted({required String requestId, required int statusCode}) {
    setState(() => status = "请求完成,状态码: $statusCode");
  }

  [@override](/user/override)
  void requestCompletedWithError(
      {required String requestId, int? statusCode, String? error}) {
    setState(() => status = "请求错误: ${error ?? "无"}");
  }

  [@override](/user/override)
  void requestStarted(
      {required String requestId, required String requestType}) {
    setState(() => status = "请求开始: $requestType");
  }
}

// 示例一个简单的GET请求,带有几个URL参数。
class ExampleRequest extends DeekWebRequest<ExampleData> {
  final double latitude;
  final double longitude;

  ExampleRequest({required this.latitude, required this.longitude});

  [@override](/user/override)
  Method get method => Method.get;

  [@override](/user/override)
  Uri get uri =>
      Uri.parse("https://api.weather.gov/points/$latitude,$longitude");

  [@override](/user/override)
  Map<String, String> get headers => {"User-Agent": "DeekWebTestApp"};

  [@override](/user/override)
  ExampleData? parseResponse(DeekWebHttpResponse response) {
    // 如果响应成功,则条件性解析响应为JSON
    if (response.statusCode == 200) {
      return ExampleData.fromJson(jsonDecode(response.body));
    } else {
      return null;
    }
  }
}

/// 简单的模型类,解析JSON数据。你也可以使用 `json_serializable` 包来创建更复杂的版本。
class ExampleData {
  String id;
  String type;

  ExampleData.fromJson(Map<String, dynamic> json)
      : id = json['id'],
        type = json['type'];
}

更多关于Flutter网页浏览插件deekweb的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter网页浏览插件deekweb的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用deekweb插件来实现网页浏览功能的示例代码。deekweb是一个Flutter插件,允许你在Flutter应用中嵌入并显示网页内容。

首先,确保你已经在pubspec.yaml文件中添加了deekweb依赖:

dependencies:
  flutter:
    sdk: flutter
  deekweb: ^最新版本号  # 请替换为实际的最新版本号

然后,运行flutter pub get来安装依赖。

接下来,在你的Flutter项目中,你可以按照以下步骤使用deekweb插件:

  1. 导入必要的包
import 'package:flutter/material.dart';
import 'package:deekweb/deekweb.dart';
  1. 创建一个包含WebView的页面
class WebViewPage extends StatelessWidget {
  final String url;

  WebViewPage({required this.url});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('WebView Demo'),
      ),
      body: DeekWebView(
        url: url,
        javascriptMode: JavascriptMode.unrestricted, // 允许JavaScript执行
        onWebViewCreated: (controller) {
          // 可以在这里保存WebView控制器,以便后续操作,如加载新的URL
        },
        onPageFinished: (url) {
          // 页面加载完成时触发
          print('Page finished loading: $url');
        },
        navigationDelegate: (request) {
          // 处理导航请求,比如拦截某些URL
          if (request.url.startsWith("https://example.com/blocked")) {
            return NavigationDecision.prevent;
          }
          return NavigationDecision.navigate;
        },
        onGestureNavigation: (direction) {
          // 处理手势导航,比如滑动返回
          print('Gesture navigation: $direction');
          return false; // 返回false表示不由插件处理手势导航
        },
      ),
    );
  }
}
  1. 在你的主应用中导航到这个页面
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter WebView Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: WebViewPage(url: 'https://www.google.com'), // 初始加载的URL
    );
  }
}

这个示例展示了如何使用deekweb插件在Flutter应用中嵌入一个WebView,并加载指定的URL。你还可以处理页面加载完成事件、拦截导航请求以及处理手势导航等高级功能。

请注意,deekweb插件的具体API可能会随着版本的更新而有所变化,因此建议查阅最新的官方文档以获取最准确的信息。

回到顶部