Flutter链接预览插件any_link_preview的使用

发布于 1周前 作者 yuanlaile 来自 Flutter

Flutter链接预览插件any_link_preview的使用

any_link_preview 是一个Flutter包,用于以美观的方式显示Web URL预览,并提供全面的自定义选项,非常适合增强聊天应用程序。它利用四种不同的解析器(HTML、JSON LD、Open Graph和Twitter Cards)来获取元数据,并支持多种显示方向(水平和垂直),同时提供了加载状态和错误处理的占位小部件。

功能特性

  • 多解析器支持:包括HTML、JSON LD、Open Graph和Twitter Cards。
  • 高度自定义:与应用设计无缝集成。
  • 可定制的占位符和错误小部件:完全自定义。
  • 媒体展示控制:选择是否在预览中显示图像等多媒体内容。
  • 缓存机制:加快后续加载速度。
  • 示例应用:帮助理解如何使用该库。

开始使用

添加依赖

首先,在pubspec.yaml文件中添加any_link_preview作为依赖项:

dependencies:
  any_link_preview: ^latest_version # 请替换为最新版本号

然后运行flutter pub get来安装这个包。

示例代码

以下是一个完整的示例代码,展示了如何在Flutter应用中使用any_link_preview插件:

import 'package:any_link_preview/any_link_preview.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final String _errorImage = "https://i.ytimg.com/vi/z8wrRRR7_qU/maxresdefault.jpg";
  final List<String> _urls = [
    "https://www.espn.in/football/soccer-transfers/story/4163866/transfer-talk-lionel-messi-tells-barcelona-hes-more-likely-to-leave-then-stay",
    "https://speakerdeck.com/themsaid/the-power-of-laravel-queues",
    "https://twitter.com/laravelphp/status/1222535498880692225",
    "https://www.youtube.com/watch?v=W1pNjxmNHNQ",
    "https://flutter.dev/",
  ];

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Any Link Preview')),
        body: SingleChildScrollView(
          padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 20),
          child: Column(
            children: List.generate(_urls.length, (index) {
              return Column(
                children: [
                  AnyLinkPreview(
                    link: _urls[index],
                    displayDirection: UIDirection.uiDirectionHorizontal,
                    showMultimedia: index != 1, // 只有第二个链接不显示多媒体
                    bodyMaxLines: 5,
                    bodyTextOverflow: TextOverflow.ellipsis,
                    titleStyle: TextStyle(
                      color: Colors.black,
                      fontWeight: FontWeight.bold,
                      fontSize: 15,
                    ),
                    bodyStyle: TextStyle(color: Colors.grey, fontSize: 12),
                    errorWidget: Container(
                      color: Colors.grey[300],
                      child: Text('Oops!'),
                    ),
                    errorImage: _errorImage,
                    onTap: (){}, // 禁用点击事件
                  ),
                  SizedBox(height: 25),
                ],
              );
            }),
          ),
        ),
      ),
    );
  }
}

使用方法

除了作为Widget直接使用外,还可以通过调用静态方法getMetadata()来获取链接的元数据并构建自定义UI。例如:

Metadata? metadata = await AnyLinkPreview.getMetadata(
  link: "https://example.com",
  cache: Duration(days: 7),
);
print(metadata?.title); // 打印标题

此外,可以使用isValidLink()函数验证URL的有效性:

bool isValid = AnyLinkPreview.isValidLink(
  "https://example.com",
  protocols: ['http', 'https'],
  hostWhitelist: ['example.com'],
);
print(isValid); // 输出true或false

自定义UI构建器

对于更复杂的场景,您可以使用AnyLinkPreview.builder来自定义预览界面:

AnyLinkPreview.builder(
  link: "https://flutter.dev/",
  itemBuilder: (context, metadata, imageProvider) => Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      if (imageProvider != null)
        Container(
          constraints: BoxConstraints(maxHeight: 200),
          decoration: BoxDecoration(
            image: DecorationImage(image: imageProvider, fit: BoxFit.cover),
          ),
        ),
      Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(metadata.title ?? '', style: TextStyle(fontWeight: FontWeight.bold)),
            Text(metadata.desc ?? '', maxLines: 2, overflow: TextOverflow.ellipsis),
            Text(metadata.url ?? ''),
          ],
        ),
      ),
    ],
  ),
)

这将允许您根据从链接提取的数据创建更加个性化的预览布局。


以上就是关于any_link_preview插件的基本介绍和使用指南,希望对您有所帮助!如果您有任何问题或者建议,请随时提出。


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

1 回复

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


当然,关于Flutter链接预览插件any_link_preview的使用,下面是一个简单的代码示例,展示了如何集成和使用这个插件来生成链接预览。

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

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

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

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

  1. 导入插件

在你的Dart文件中导入any_link_preview插件:

import 'package:any_link_preview/any_link_preview.dart';
import 'package:flutter/material.dart';
  1. 创建预览生成器

使用LinkPreviewBuilder小部件来生成链接预览。下面是一个完整的示例,包括一个简单的UI来输入URL并显示预览:

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Link Preview Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: LinkPreviewScreen(),
    );
  }
}

class LinkPreviewScreen extends StatefulWidget {
  @override
  _LinkPreviewScreenState createState() => _LinkPreviewScreenState();
}

class _LinkPreviewScreenState extends State<LinkPreviewScreen> {
  final TextEditingController _controller = TextEditingController();
  LinkPreviewData? _previewData;

  void _fetchPreview(String url) async {
    setState(() {
      _previewData = null; // Reset preview data while fetching
    });
    try {
      _previewData = await LinkPreviewBuilder.fetchPreview(url);
    } catch (e) {
      print("Error fetching preview: $e");
    }
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Link Preview Example'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            TextField(
              controller: _controller,
              decoration: InputDecoration(
                labelText: 'Enter URL',
                border: OutlineInputBorder(),
              ),
              keyboardType: TextInputType.url,
              onEditingComplete: () async {
                if (_controller.text.isNotEmpty) {
                  _fetchPreview(_controller.text);
                }
              },
            ),
            SizedBox(height: 16),
            if (_previewData != null)
              LinkPreviewBuilder(
                linkPreviewData: _previewData!,
                placeholder: CircularProgressIndicator(),
                errorWidget: Text('Failed to load preview'),
                builder: (context, metadata) {
                  return Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                      if (metadata.title != null)
                        Text(
                          metadata.title!,
                          style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
                        ),
                      if (metadata.description != null)
                        Text(
                          metadata.description!,
                          style: TextStyle(fontSize: 16, color: Colors.grey),
                        ),
                      if (metadata.thumbnailUrl != null)
                        Image.network(
                          metadata.thumbnailUrl!,
                          width: double.infinity,
                          height: 200,
                          fit: BoxFit.cover,
                        ),
                    ],
                  );
                },
              ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          if (_controller.text.isNotEmpty) {
            _fetchPreview(_controller.text);
          }
        },
        tooltip: 'Fetch Preview',
        child: Icon(Icons.link),
      ),
    );
  }
}

在这个示例中:

  • 用户可以在文本字段中输入一个URL。
  • 当用户完成编辑(或点击浮动操作按钮)时,会调用_fetchPreview方法来获取链接预览。
  • 如果预览数据成功获取,LinkPreviewBuilder小部件将使用这些数据来显示预览内容,包括标题、描述和缩略图。
  • 如果在获取预览时发生错误,将显示一个错误小部件。

这个示例提供了一个基本的使用any_link_preview插件的方法,你可以根据需求进一步自定义和扩展。

回到顶部