Flutter加载自定义CSS样式文件方法

1. 使用 flutter_html 包(推荐)

如果你需要在 Flutter 中显示 HTML 并应用 CSS 样式,可以使用 flutter_html 包:

Dart 复制代码
import 'package:flutter_html/flutter_html.dart';
import 'package:flutter/services.dart' show rootBundle;

class HtmlWithCssPage extends StatefulWidget {
  @override
  _HtmlWithCssPageState createState() => _HtmlWithCssPageState();
}

class _HtmlWithCssPageState extends State<HtmlWithCssPage> {
  String htmlContent = '';
  String cssContent = '';

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

  Future<void> _loadResources() async {
    // 加载 HTML 文件
    htmlContent = await rootBundle.loadString('assets/sample.html');
    
    // 加载 CSS 文件
    cssContent = await rootBundle.loadString('assets/styles.css');
    
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('HTML with CSS')),
      body: SingleChildScrollView(
        child: Html(
          data: '''
            <style>$cssContent</style>
            $htmlContent
          ''',
          // 自定义样式处理
          style: {
            "body": Style(
              fontSize: FontSize(16.0),
              color: Colors.black,
            ),
            "h1": Style(
              color: Colors.blue,
              fontWeight: FontWeight.bold,
            ),
          },
        ),
      ),
    );
  }
}

pubspec.yaml 中配置:

Dart 复制代码
flutter:
  assets:
    - assets/sample.html
    - assets/styles.css

2. 对于 Web 平台的特殊处理

直接添加 CSS 到 Web 页面

web/index.html 中添加 CSS 链接:

Dart 复制代码
<!DOCTYPE html>
<html>
<head>
  <!-- 其他 meta 标签 -->
  <link href="styles/custom.css" rel="stylesheet">
</head>
<body>
  <script src="main.dart.js" type="application/javascript"></script>
</body>
</html>

动态注入 CSS

Dart 复制代码
import 'dart:html' as html;

void injectCustomCss() {
  final styleElement = html.StyleElement();
  styleElement.id = 'custom-styles';
  styleElement.text = '''
    .custom-class {
      color: red;
      font-size: 20px;
    }
  ''';
  html.document.head!.append(styleElement);
}

3. 使用 webview_flutter 显示带样式的 HTML

Dart 复制代码
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

class WebViewWithCss extends StatefulWidget {
  @override
  _WebViewWithCssState createState() => _WebViewWithCssState();
}

class _WebViewWithCssState extends State<WebViewWithCss> {
  late WebViewController _controller;

  Future<void> _loadHtmlWithCss() async {
    final htmlContent = await rootBundle.loadString('assets/content.html');
    final cssContent = await rootBundle.loadString('assets/styles.css');
    
    final fullHtml = '''
      <!DOCTYPE html>
      <html>
      <head>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <style>$cssContent</style>
      </head>
      <body>
        $htmlContent
      </body>
      </html>
    ''';
    
    _controller.loadHtmlString(fullHtml);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('WebView with CSS')),
      body: WebView(
        initialUrl: 'about:blank',
        javascriptMode: JavascriptMode.unrestricted,
        onWebViewCreated: (controller) {
          _controller = controller;
          _loadHtmlWithCss();
        },
      ),
    );
  }
}

4. 创建 assets 文件夹和文件

Dart 复制代码
lib/
assets/
├── styles.css
└── sample.html

styles.css 示例:

css 复制代码
body {
  font-family: Arial, sans-serif;
  line-height: 1.6;
  color: #333;
}

h1 {
  color: #2c3e50;
  border-bottom: 2px solid #3498db;
}

.highlight {
  background-color: #fffacd;
  padding: 10px;
  border-radius: 5px;
}

pubspec.yaml 配置:

Dart 复制代码
flutter:
  assets:
    - assets/styles.css
    - assets/sample.html

注意事项

  1. 性能考虑:大量使用 HTML/CSS 可能会影响性能

  2. 平台限制:CSS 样式主要在 Web 平台有效,移动端可能需要替代方案

  3. 样式冲突:Flutter 样式和 CSS 样式可能会冲突

  4. 安全性:动态加载 HTML/CSS 时注意 XSS 攻击防护

替代方案

如果不需要真正的 HTML/CSS,考虑使用 Flutter 的原生样式系统:

Dart 复制代码
// 在 ThemeData 中定义全局样式
MaterialApp(
  theme: ThemeData(
    textTheme: TextTheme(
      headline1: TextStyle(
        fontSize: 24,
        fontWeight: FontWeight.bold,
        color: Colors.blue,
      ),
      bodyText1: TextStyle(
        fontSize: 16,
        color: Colors.black87,
      ),
    ),
  ),
);

// 使用 TextStyle
Text(
  'Styled Text',
  style: TextStyle(
    fontSize: 20,
    color: Colors.red,
    fontWeight: FontWeight.bold,
  ),
);

使用哪种方式我们要根据具体需求具体分析。

相关推荐
子兮曰21 小时前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰21 小时前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万21 小时前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝21 小时前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋1 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁1 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王95271 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大1 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师1 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学1 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端