Flutter文本编辑与展示插件flutter_portabletext_fork的使用

Flutter文本编辑与展示插件flutter_portabletext_fork的使用

简介

flutter_portabletext_fork 是对 flutter_portabletext 包的修改版本,用于在 Flutter 应用中渲染来自 Sanity.io 的富文本内容。它遵循 PortableText 规范,允许开发者轻松展示复杂的富文本内容。

演示图


特性

  • 渲染符合 PortableText 规范的富文本。
  • 支持链接点击事件。
  • 提供样式自定义选项。

安装

在项目的 pubspec.yaml 文件中添加依赖:

dependencies:
  flutter_portabletext_fork: ^版本号

然后运行以下命令安装:

flutter pub get

使用方法

以下是一个完整的示例代码,展示如何使用 flutter_portabletext_fork 来渲染富文本。

示例代码

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_portabletext_fork/flutter_portabletext.dart';
import 'package:flutter_portabletext_fork/portable_text.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter PortableText Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.orangeAccent),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter PortableText Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<PortableText>? portableText;

  @override
  void initState() {
    super.initState();

    // 初始化富文本数据(从 JSON 文件加载)
    initPortableTextWithJson() async {
      rootBundle.loadString('assets/ex.json').then((value) async {
        final data = await json.decode(value) as List<dynamic>;
        final List<PortableText> listPortableText = [];
        for (var dynamicPort in data) {
          final portableText = PortableText.fromJson(dynamicPort);
          listPortableText.add(portableText);
        }
        setState(() {
          portableText = listPortableText;
        });
      });
    }

    initPortableTextWithJson();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: SingleChildScrollView(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          children: <Widget>[
            if (portableText != null)
              SizedBox(
                width: double.infinity,
                child: PortableTextRichText(
                  portableText: portableText!, // 渲染的富文本列表
                  onTapLink: (value) => print(value), // 点击链接时触发回调
                ),
              ),
          ],
        ),
      ),
    );
  }
}

说明

  1. 初始化数据

    • 使用 rootBundle.loadString 加载本地 JSON 文件。
    • 将 JSON 数据解析为 List<dynamic>,并将其转换为 PortableText 对象。
  2. 渲染富文本

    • 使用 PortableTextRichText 小部件来展示富文本内容。
    • onTapLink 回调可以捕获用户点击链接的行为。
  3. 自定义样式: 如果需要更改默认样式,可以通过配置 mapStyle 和其他参数来自定义。


自定义样式

如果需要修改默认的文本样式,可以通过以下方式调整:

this.mapStyle = const {
  'h1': TextStyle(fontSize: 24),
  'h2': TextStyle(fontSize: 22),
  'h3': TextStyle(fontSize: 20),
  'h4': TextStyle(fontSize: 18),
  'h5': TextStyle(fontSize: 16),
  'h6': TextStyle(fontSize: 14),
  'blockquote': TextStyle(fontSize: 12),
},
this.quoteStyle = const TextStyle(
  fontSize: 12,
),
this.normalStyle = const TextStyle(fontSize: 10),
this.externalLinkColor = const Color(0xFF0645AD),
this.codeBackgroundColor = Colors.grey,
this.externalLinkDecoration = TextDecoration.underline,
1 回复

更多关于Flutter文本编辑与展示插件flutter_portabletext_fork的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


flutter_portabletext_fork 是一个用于在 Flutter 应用中解析和展示 Portable Text 的插件。Portable Text 是一种基于 JSON 的富文本格式,通常用于无头 CMS(如 Sanity)中。这个插件可以帮助你将 Portable Text 数据解析为 Flutter 的 Widget 树,从而在应用中展示富文本内容。

安装

首先,你需要在 pubspec.yaml 文件中添加 flutter_portabletext_fork 依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_portabletext_fork: ^0.0.1

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

基本用法

  1. 导入包

    import 'package:flutter_portabletext_fork/flutter_portabletext_fork.dart';
  2. 解析和展示 Portable Text

    假设你有一个 Portable Text 的 JSON 数据,你可以使用 PortableText 组件来解析和展示它。

    class MyPortableTextWidget extends StatelessWidget {
      final List<dynamic> portableTextData = [
        {
          "_type": "block",
          "style": "normal",
          "markDefs": [],
          "children": [
            {
              "_type": "span",
              "text": "Hello, ",
              "marks": []
            },
            {
              "_type": "span",
              "text": "World!",
              "marks": ["strong"]
            }
          ]
        }
      ];
    
      @override
      Widget build(BuildContext context) {
        return PortableText(
          data: portableTextData,
          defaultStyle: TextStyle(fontSize: 16),
          customStyles: {
            'strong': TextStyle(fontWeight: FontWeight.bold),
          },
        );
      }
    }

    在这个例子中,portableTextData 是一个包含 Portable Text 数据的 JSON 数组。PortableText 组件会解析这个数据,并根据 defaultStylecustomStyles 来应用样式。

  3. 自定义样式

    你可以通过 customStyles 参数来定义自定义样式。customStyles 是一个 Map<String, TextStyle>,其中键是标记名称(如 "strong"),值是对应的 TextStyle

  4. 处理复杂结构

    Portable Text 可以包含复杂的结构,如列表、链接、图片等。flutter_portabletext_fork 插件支持这些复杂结构的解析和展示。你可以根据需要自定义这些组件的展示方式。

高级用法

  1. 自定义块渲染

    你可以通过 blockBuilders 参数来自定义特定类型的块的渲染方式。例如,如果你想自定义 blockquote 的渲染,可以这样做:

    PortableText(
      data: portableTextData,
      blockBuilders: {
        'blockquote': (context, block, children) {
          return Container(
            padding: EdgeInsets.all(10),
            decoration: BoxDecoration(
              border: Border(left: BorderSide(color: Colors.grey, width: 4)),
            ),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: children,
            ),
          );
        },
      },
    );
  2. 自定义标记渲染

    你可以通过 markBuilders 参数来自定义特定标记的渲染方式。例如,如果你想自定义 link 标记的渲染,可以这样做:

    PortableText(
      data: portableTextData,
      markBuilders: {
        'link': (context, mark, text) {
          return GestureDetector(
            onTap: () {
              // 处理链接点击
            },
            child: Text(
              text,
              style: TextStyle(color: Colors.blue, decoration: TextDecoration.underline),
            ),
          );
        },
      },
    );
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!