Flutter文本提及插件cr_mentions的使用

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

Flutter文本提及插件cr_mentions的使用

目录

截图

开始使用

在项目中添加插件:

dependencies:
  cr_mentions: ^0.0.1

使用方法

此插件适用于需要在文本中提及某人的场景。

要跟踪提及,可以使用MentionTextController作为文本字段的控制器。

要显示提及,可以使用MentionTextMentionWidget

控制器

MentionTextController
// `tag` - 提及时使用的符号,默认为 `@`
// `mentions` - 当前检测到的提及列表,每次文本更改时都会重新生成
// `lastMention` - 最后一个可编辑的提及
// `insertMention` - 在当前可编辑的提及位置插入提及
// `makeQuerySuggestions` - 返回用于搜索建议的字符串。如果返回空字符串,则仅输入了符号;如果返回null,则无建议。否则将返回所有匹配的建议。
// `replaceLastMentionWithText` - 将最后一个提及转换为普通文本
// `prepareForEditingMode` - 在带有提及的文本字段的编辑模式下初始化时调用此方法,并传递先前设置的提及列表
// `getMentionsListWithoutTag` - 添加id,移除`tag`符号并插入第一个提及。例如,回复评论时(带位置偏移)
// `getTextWithFirstMention` - 如果在`getMentionsListWithoutTag`中添加第一个提及,应返回已包含该提及的正确字符串

return MessageModel(
  text: _mentionCtr.getTextWithFirstMention(replyModel),
  mentions: _mentionCtr.getMentionsListWithoutTag(
    isTextTrimmed: false,
    firstMention: replyModel,
  ) ?? [],
);
使用控制器
final _lastMention = ValueNotifier<MentionModel?>(null);
late final _mentionCtr = MentionTextController(lastMention: _lastMention);

...
TextFormField(
  controller: _mentionCtr,
),
...

模型

MentionData

如果你希望任何模型专门用于提及,需要将其包装在MentionData<T>中。

MentionData<UserModel>(
  mentionName: 'xerown',
  data: UserModel(
    firstName: 'Mark',
    lastName: 'Robinson',
  ),
  id: 0,
),
MentionModel

如果你希望提及在文本中显示,创建一个存储所有提及的模型。

class MessageModel {
  MessageModel({
    required this.text,
    required this.mentions,
  });

  final String text;
  final List<MentionModel> mentions;
}

MessageModel(
  text: _mentionCtr.text,
  mentions: _mentionCtr.getMentionsListWithoutTag(isTextTrimmed: true) ?? [],
)

部件

MentionText

此部件用于高亮显示文本中的提及。

MentionText(
  message.text,
  mentions: message.mentions,
  style: const TextStyle(color: Colors.black),
  mentionStyle: const TextStyle(color: Colors.deepOrange),
  onMentionTap: onMentionModel,
)
MentionWidget

如果您希望提及看起来与普通的高亮文本不同,可以使用此部件。

MentionWidget(
  message.text,
  mentions: message.mentions,
  paddingText: const EdgeInsets.symmetric(vertical: 4),
  mentionWidgetBuilder: _mentionBuilder,
),

Widget _mentionBuilder(MentionModel mention) {
  return Container(
    decoration: BoxDecoration(
      borderRadius: BorderRadius.circular(4),
      color: Colors.deepOrange.shade100,
    ),
    margin: const EdgeInsets.symmetric(horizontal: 2, vertical: 2),
    padding: const EdgeInsets.all(4),
    child: Text(
      mention.fullMention,
      style: const TextStyle(color: Colors.deepOrange),
    ),
  );
}

完整示例Demo

import 'package:cr_mentions_example/pages/add_text_page.dart';
import 'package:cr_mentions_example/pages/saved_text_page.dart';
import 'package:cr_mentions_example/pages/simple_example_page.dart';
import 'package:flutter/material.dart';

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

class Example extends StatelessWidget {
  const Example({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: MainPage(),
    );
  }
}

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

  [@override](/user/override)
  State<MainPage> createState() => _MainPageState();
}

class _MainPageState extends State<MainPage> {
  static const items = [
    BottomNavigationBarItem(
      label: 'Add Text',
      icon: Icon(Icons.comment),
    ),
    BottomNavigationBarItem(
      label: 'Saved Text',
      icon: Icon(Icons.list),
    ),
    BottomNavigationBarItem(
      label: 'Short example',
      icon: Icon(Icons.short_text),
    ),
  ];

  static const _pages = [
    AddTextPage(),
    SavedTextPage(),
    SimpleExamplePage(),
  ];

  int _currentIndex = 0;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      bottomNavigationBar: BottomNavigationBar(
        backgroundColor: Colors.white,
        items: items,
        currentIndex: _currentIndex,
        selectedItemColor: Colors.deepOrange,
        unselectedItemColor: Colors.grey,
        onTap: _onTapped,
      ),
      body: _pages[_currentIndex],
    );
  }

  void _onTapped(int index) {
    setState(() => _currentIndex = index);
  }
}

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

1 回复

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


当然,下面是一个关于如何在Flutter项目中使用cr_mentions插件来实现文本提及功能的代码案例。这个插件允许你在文本输入中检测并高亮显示提及的用户名。

首先,确保你的Flutter项目已经设置好,并在pubspec.yaml文件中添加cr_mentions依赖:

dependencies:
  flutter:
    sdk: flutter
  cr_mentions: ^x.y.z  # 请替换为最新版本号

然后运行flutter pub get来获取依赖。

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

  1. 导入必要的包
import 'package:flutter/material.dart';
import 'package:cr_mentions/cr_mentions.dart';
  1. 创建一个数据模型来表示可提及的用户
class User {
  final String id;
  final String displayName;

  User({required this.id, required this.displayName});
}
  1. 创建一个列表来存储可提及的用户
List<User> users = [
  User(id: '1', displayName: '@Alice'),
  User(id: '2', displayName: '@Bob'),
  User(id: '3', displayName: '@Charlie'),
];
  1. 创建一个MentionsController并配置它
MentionsController _controller = MentionsController(
  textEditingController: TextEditingController(),
  config: MentionsConfig(
    positionInText: (user) => '@' + user.displayName,
    onChanged: (text) {},
    onMentionSelected: (user) {
      print('User ${user.displayName} mentioned');
    },
    users: users,
    typeAhead: true, // 启用自动完成
  ),
);
  1. 在UI中使用MentionsTextField
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Mentions Example'),
        ),
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: MentionsTextField(
            controller: _controller,
            decoration: InputDecoration(
              border: OutlineInputBorder(),
              labelText: 'Type a message...',
            ),
          ),
        ),
      ),
    );
  }
}
  1. 处理用户提及(可选)

你可以在MentionsConfigonMentionSelected回调中处理用户提及的逻辑,比如发送消息到服务器或更新UI。

onMentionSelected: (user) {
  // 这里可以添加你希望在用户被提及时执行的逻辑
  print('User ${user.displayName} (${user.id}) mentioned');
},

以上代码展示了如何在Flutter应用中使用cr_mentions插件来实现文本提及功能。你可以根据实际需求进一步定制和扩展这个示例。

回到顶部