Flutter文本高亮插件ruffde_highlights的使用

Flutter文本高亮插件ruffde_highlights的使用

使用

HeightLightPageView 需要至少三个参数:itemBuilderpageLengthstoryLength

/// 最小示例以解释用法。
return Scaffold(
  body: HeightLightPageView(
    itemBuilder: (context, pageIndex, storyIndex) {
      return Center(
        child: Text("Index of PageView: $pageIndex Index of story on each page: $storyIndex"),
      );
    },
    storyLength: (pageIndex) {
      return 3;
    },
    pageLength: 4,
  );
  • itemBuilder 是构建故事内容所必需的。它会根据页面索引和页面上的故事索引来调用。
  • storyLength 决定每页的故事长度。上面的例子总是返回3,但它应该依赖于 pageIndex 参数。
  • pageLength 就是 HeightLightPageView 的长度。

上面的例子只是通过4页展示了12个故事,这并不实用。

以下是正确的用法,从示例中提取出来:

return Scaffold(
  body: HeightLightPageView(
    itemBuilder: (context, pageIndex, storyIndex) {
      final user = sampleUsers[pageIndex];
      final story = user.stories[storyIndex];
      return Stack(
        children: [
          Positioned.fill(
            child: Container(color: Colors.black),
          ),
          Positioned.fill(
            child: Image.network(
              story.imageUrl,
              fit: BoxFit.cover,
            ),
          ),
          Padding(
            padding: const EdgeInsets.only(top: 44, left: 8),
            child: Row(
              children: [
                Container(
                  height: 32,
                  width: 32,
                  decoration: BoxDecoration(
                    image: DecorationImage(
                      image: NetworkImage(user.imageUrl),
                      fit: BoxFit.cover,
                    ),
                    shape: BoxShape.circle,
                  ),
                ),
                const SizedBox(
                  width: 8,
                ),
                Text(
                  user.userName,
                  style: TextStyle(
                    fontSize: 17,
                    color: Colors.white,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ],
            ),
          ),
        ],
      );
    },
    gestureItemBuilder: (context, pageIndex, storyIndex) {
      return Align(
        alignment: Alignment.topRight,
        child: Padding(
          padding: const EdgeInsets.only(top: 32),
          child: IconButton(
            padding: EdgeInsets.zero,
            color: Colors.white,
            icon: Icon(Icons.close),
            onPressed: () {
              Navigator.pop(context);
            },
          ),
        ),
      );
    },
    pageLength: sampleUsers.length,
    storyLength: (int pageIndex) {
      return sampleUsers[pageIndex].stories.length;
    },
    onPageLimitReached: () {
      Navigator.pop(context);
    },
  ),
);
  • gestureItemBuilder 是用于需要手势操作的部件的构建器。

    在这种情况下,关闭页面的 IconButton 在回调中。

    您不能将手势部件放置在 itemBuilder 中,因为默认情况下它们会被覆盖且禁用。

  • onPageLimitReached 在最后一个故事完成后被调用。

  • 建议使用具有两层的数据模型。在这种情况下,具有 StoryModel 列表的 UserModel

/// 示例数据模型
class UserModel {
  UserModel(this.stories, this.userName, this.imageUrl);

  final List<HeightLightModel> stories;
  final String userName;
  final String imageUrl;
}

class HeightLightModel {
  HeightLightModel(this.imageUrl);

  final String imageUrl;
}

示例代码

import 'package:flutter/material.dart';

import 'package:ruffde_highlights/highlight_page_views/heighlight_page_view.dart';

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

class UserModel {
  UserModel(this.stories, this.userName, this.imageUrl);

  final List<HeightLightModel> stories;
  final String userName;
  final String imageUrl;
}

class HeightLightModel {
  HeightLightModel(this.imageUrl);

  final String imageUrl;
}

class MyApp extends StatelessWidget {
  // 这个组件是你的应用的根组件。
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          child: Text('显示故事'),
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(
                builder: (context) {
                  return HeighLightPage();
                },
              ),
            );
          },
        ),
      ),
    );
  }
}

class HeighLightPage extends StatefulWidget {
  HeighLightPage({Key? key}) : super(key: key);

  [@override](/user/override)
  _HeighLightPageState createState() => _HeighLightPageState();
}

class _HeighLightPageState extends State<HeighLightPage> {
  late ValueNotifier<IndicatorAnimationCommand> indicatorAnimationController;
  final sampleUsers = [
    UserModel([
      HeightLightModel(
          "https://images.unsplash.com/photo-1609167830240-fc81e9cfd9bf?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=668&q=80"),
      HeightLightModel(
          "https://images.unsplash.com/photo-1561758033-7e924f619b47?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=668&q=80"),
      HeightLightModel(
          "https://images.unsplash.com/photo-1621792907526-e69888069079?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=668&q=80"),
      HeightLightModel(
          "https://images.unsplash.com/photo-1621792907789-666f0e69ea03?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=668&q=80"),
    ], "Guta Restu",
        "https://images.unsplash.com/photo-1609262772830-0decc49ec18c?ixid=MXwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwzMDF8fHxlbnwwfHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60"),
    UserModel([
      HeightLightModel(
          "https://images.unsplash.com/photo-1621797350488-fb28c9217e3b?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=2734&q=80"),
    ], "Kumar Restu",
        "https://images.unsplash.com/photo-1601758125946-6ec2ef64daf8?ixid=MXwxMjA3fDF8MHxlZGl0b3JpYWwtZmVlZHwzMjN8fHxlbnwwfHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60"),
    UserModel([
      HeightLightModel(
          "https://images.unsplash.com/photo-1621792907526-e69888069079?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=668&q=80"),
      HeightLightModel(
          "https://images.unsplash.com/photo-1621792907789-666f0e69ea03?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=668&q=80"),
      HeightLightModel(
          "https://images.unsplash.com/photo-1505252585461-04db1eb84625?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=704&q=80"),
    ], "Pandeyji Restur",
        "https://images.unsplash.com/photo-1609127102567-8a9a21dc27d8?ixid=MXwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwzOTh8fHxlbnwwfHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60"),
  ];

  [@override](/user/override)
  void initState() {
    super.initState();
    indicatorAnimationController = ValueNotifier<IndicatorAnimationCommand>(
        IndicatorAnimationCommand.resume);
  }

  [@override](/user/override)
  void dispose() {
    indicatorAnimationController.dispose();
    super.dispose();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      body: HeightLightPageView(
        itemBuilder: (context, pageIndex, storyIndex) {
          final user = sampleUsers[pageIndex];
          final story = user.stories[storyIndex];
          return Stack(
            children: [
              Positioned.fill(
                child: Container(color: Colors.black),
              ),
              Positioned.fill(
                child: Image.network(
                  story.imageUrl,
                  fit: BoxFit.cover,
                ),
              ),
              Padding(
                padding: const EdgeInsets.only(top: 44, left: 8),
                child: Row(
                  children: [
                    Container(
                      height: 32,
                      width: 32,
                      decoration: BoxDecoration(
                        image: DecorationImage(
                          image: NetworkImage(user.imageUrl),
                          fit: BoxFit.cover,
                        ),
                        shape: BoxShape.circle,
                      ),
                    ),
                    const SizedBox(
                      width: 8,
                    ),
                    Text(
                      user.userName,
                      style: TextStyle(
                        fontSize: 17,
                        color: Colors.white,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                  ],
                ),
              ),
            ],
          );
        },
        gestureItemBuilder: (context, pageIndex, storyIndex) {
          return Stack(children: [
            Align(
              alignment: Alignment.topRight,
              child: Padding(
                padding: const EdgeInsets.only(top: 32),
                child: IconButton(
                  padding: EdgeInsets.zero,
                  color: Colors.white,
                  icon: Icon(Icons.close),
                  onPressed: () {
                    Navigator.pop(context);
                  },
                ),
              ),
            ),
            if (pageIndex == 0)
              Center(
                child: ElevatedButton(
                  child: Text('显示模态底部菜单'),
                  onPressed: () async {
                    indicatorAnimationController.value =
                        IndicatorAnimationCommand.pause;
                    await showModalBottomSheet(
                      context: context,
                      builder: (context) => SizedBox(
                        height: MediaQuery.of(context).size.height / 2,
                        child: Padding(
                          padding: EdgeInsets.all(24),
                          child: Text(
                            '看!指示器现在暂停了\n\n'
                            '它将在关闭模态底部菜单后继续。',
                            style: Theme.of(context).textTheme.headline5,
                            textAlign: TextAlign.center,
                          ),
                        ),
                      ),
                    );
                    indicatorAnimationController.value =
                        IndicatorAnimationCommand.resume;
                  },
                ),
              ),
          ]);
        },
        indicatorAnimationController: indicatorAnimationController,
        initialStoryIndex: (pageIndex) {
          if (pageIndex == 0) {
            return 1;
          }
          return 0;
        },
        pageLength: sampleUsers.length,
        storyLength: (int pageIndex) {
          return sampleUsers[pageIndex].stories.length;
        },
        onPageLimitReached: () {
          Navigator.pop(context);
        },
      ),
    );
  }
}

更多关于Flutter文本高亮插件ruffde_highlights的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter文本高亮插件ruffde_highlights的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


ruffde_highlights 是一个用于在 Flutter 应用中实现文本高亮显示的插件。它可以让你轻松地在文本中高亮显示特定的关键词、短语或正则表达式匹配的内容。以下是如何使用 ruffde_highlights 插件的基本步骤:

1. 添加依赖

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

dependencies:
  flutter:
    sdk: flutter
  ruffde_highlights: ^1.0.0  # 请使用最新版本

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

2. 导入包

在你的 Dart 文件中导入 ruffde_highlights 包:

import 'package:ruffde_highlights/ruffde_highlights.dart';

3. 使用 TextHighlighter

TextHighlighterruffde_highlights 提供的核心组件,用于高亮显示文本。你可以通过设置 highlights 属性来指定需要高亮的内容。

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

class HighlightTextExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Text Highlighter Example'),
      ),
      body: Center(
        child: TextHighlighter(
          text: 'This is a sample text with some keywords to highlight.',
          highlights: [
            Highlight(text: 'sample', style: TextStyle(backgroundColor: Colors.yellow)),
            Highlight(text: 'keywords', style: TextStyle(backgroundColor: Colors.orange)),
          ],
        ),
      ),
    );
  }
}

4. 配置 Highlight

Highlight 类用于定义需要高亮的文本及其样式。你可以通过 text 属性指定需要高亮的关键词,通过 style 属性指定高亮样式。

Highlight(
  text: 'highlight',
  style: TextStyle(
    backgroundColor: Colors.yellow,
    color: Colors.red,
    fontWeight: FontWeight.bold,
  ),
)

5. 支持正则表达式

ruffde_highlights 还支持使用正则表达式来匹配需要高亮的内容。你可以使用 pattern 属性来指定正则表达式。

TextHighlighter(
  text: 'This is a test with numbers 123 and 456.',
  highlights: [
    Highlight(pattern: r'\d+', style: TextStyle(backgroundColor: Colors.blue)),
  ],
)

6. 自定义高亮逻辑

如果你需要更复杂的高亮逻辑,可以使用 highlightBuilder 属性来自定义高亮部分的渲染。

TextHighlighter(
  text: 'This is a custom highlight example.',
  highlights: [
    Highlight(text: 'custom', style: TextStyle(backgroundColor: Colors.green)),
  ],
  highlightBuilder: (context, text, style) {
    return Container(
      padding: EdgeInsets.all(2),
      decoration: BoxDecoration(
        color: Colors.green,
        borderRadius: BorderRadius.circular(4),
      ),
      child: Text(
        text,
        style: style,
      ),
    );
  },
)
回到顶部