如何在 Flutter 的消息中实现用户提及?

Posted

技术标签:

【中文标题】如何在 Flutter 的消息中实现用户提及?【英文标题】:How to implement user mentions in messages on Flutter? 【发布时间】:2019-12-21 05:02:35 【问题描述】:

我需要在消息中实现用户提及,就像在 Flutter 上的流行信使中一样。当我单击输入字段中的某个按钮时,有必要出现一个小部件,其中包含我提到的用户的姓名和图像。

我试过extended_text_field,但它有问题

【问题讨论】:

你找到解决办法了吗? 【参考方案1】:

试试这个

UserTextfield 类

class UserTextfield extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return BlocProvider(
      create: (context) => UserBloc(UrlUserRepository()),
      child: UserTextfieldPage(),
    );
  


class UserTextfieldPage extends StatefulWidget 
  @override
  _UserTextfieldPageState createState() => _UserTextfieldPageState();


class _UserTextfieldPageState extends State<UserTextfieldPage> 
  bool _visibility = false;

  @override
  Widget build(BuildContext context) 

    return BlocBuilder<UserBloc, UserState>(
      builder: (context, state) 
        return Column(
          children: <Widget>[
            TextField(
              onChanged: (value) 
                final _tagRegex =
                    RegExp(r"\B@\w*[a-zA-Z]+\w*", caseSensitive: false);
                final sentences = value.split('\n');
                sentences.forEach(
                  (sentence) 
                    final words = sentence.split(' ');
                    String withat = words.last;
                    if (_tagRegex.hasMatch(withat)) 
                      String withoutat = withay.substring(1);
                      BlocProvider.of<UserBloc>(context).add(
                        Searchuser(searchtext: withoutat),
                      );
                      setState(() 
                        _visibility = true;
                      );
                     else 
                      setState(() 
                        _visibility = false;
                      );
                    
                  ,
                );
              ,
            ),
            _listviewWidget(state),
          ],
        );
      ,
    );
  

  Widget _listviewWidget(UserState state) 
    if (state is UserLoading) 
      return Center(
        child: CircularProgressIndicator(
          valueColor: new AlwaysStoppedAnimation<Color>(Colors.black),
        ),
      );
     else if (state is UserLoaded) 
      return Expanded(
        child: Visibility(
          visible: _visibility,
          maintainSize: true,
          maintainAnimation: true,
          maintainState: true,
          child: ListView.builder(
            itemCount: state.userModel.userResult.length,
            itemBuilder: (context, index) 
              var listitem = state.userModel.userResult[index];
              return ListTile(
                title: Text(listitem.topic),
              );
            ,
          ),
        ),
      );
     else if (state is UserError) 
      return Align(
        alignment: Alignment.topCenter,
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Text(state.message),
        ),
      );
     else 
      return Container();
    
  

UserBloc 类

import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:your project file location/user_model.dart';
import 'package:your project file location/user_repository.dart';

part 'user_event.dart';
part 'user_state.dart';

class UserBloc extends Bloc<UserEvent, UserState> 
  final UserRepository userRepository;

  UserBloc(this.userRepository)
      : assert(userRepository != null),
        super(UserInitial());

  @override
  Stream<UserState> mapEventToState(
    UserEvent event,
  ) async* 
    if (event is Searchuser) 
      yield UserLoading();
      try 
        final userModel = await userRepository.getuser(event.searchtext);
        yield UserLoaded(userModel);
       catch (_) 
        yield UserError(message: 'Something went to wrong');
      
    
  

UserEvent 类

part of 'User_bloc.dart';

abstract class UserEvent extends Equatable
  const UserEvent();


class Searchuser extends UserEvent 
  final String searchtext;

  const Searchuser(this.searchtext);

  List<Object> get props => [searchtext];

  @override
  String toString() =>
      'Searchuser  searchtext: $searchtext ';

UserState 类

part of 'user_bloc.dart';

abstract class UserState extends Equatable 
  const UserState();


class UserInitial extends UserState 
  @override
  List<Object> get props => [];


class UserLoading extends UserState 
  const UserLoading();

  @override
  List<Object> get props => [];


class UserLoaded extends UserState 
  final UserModel userModel;

  const UserLoaded(this.userModel);

  @override
  List<Object> get props => [userModel];


class UserError extends UserState 
  final String message;

  const UserError(this.message);

  @override
  List<Object> get props => [message];

  @override
  String toString() => 'UserError  message: $message ';

UserModel 类

import 'package:equatable/equatable.dart';

class UserModel extends Equatable
  final bool error;
  final List<UserResult> userResult;

  UserModel(this.error, this.userResult);

  factory UserModel.fromJson(Map<String, dynamic> json) 
    var resultList = json['data'] as List;

    List<UserResult> userResult =
        resultList.map((i) => UserResult.fromJson(i)).toList();

    return UserModel(
      error: json['error'],
      userResult: userResult,
    );
  

  @override
  List<Object> get props => [error, userResult];


class UserResult extends Equatable 
  final String name;

  UserResult(this.name);

  factory UserResult.fromJson(Map<String, dynamic> json) 
    return UserResult(
      name: json["name"],
    );
  
  @override
  List<Object> get props => [name];
  

UserRepository 类

import 'dart:async';
import 'dart:convert';

import 'package:http/http.dart' as http;
import 'package:your project file location/user_model.dart';

abstract class UserRepository 
  Future<UserModel> getuser(String searchtext);


class UrlUserRepository implements UserRepository 
  @override
  Future<UserModel> getuser(String searchtext) async 
    Map<String, dynamic> stringParams = 'searchtext': searchtext;

    var uriResponse = await http.post(your api, body: stringParams);

    if (uriResponse.statusCode == 200) 
      final String res = uriResponse.body;
      var resdata = json.decode(res);
      return UserModel.fromJson(resdata);
     else 
      throw Exception('please, try again!');
    
  

json 数据


    "data": [
        
            "name": "bharat"
        ,
        
            "name": "india"
        ,
        
            "name": "abbcc"
        ,
        
            "name": "abc"
        ,
        
            "name": "user"
        ,
        
            "name": "user1"
        ,
        
            "name": "user2"
        ,
        
            "name": "user3"
        ,
        
            "name": "user4"
        
    ],
    "error": false,
    "message": "user feteched"

【讨论】:

以上是关于如何在 Flutter 的消息中实现用户提及?的主要内容,如果未能解决你的问题,请参考以下文章

如何在flutter中实现包月? (新方法)

如何在 Flutter Dart 中实现插件架构

如何在 Flutter 中实现应用内购买订阅?

如何在 Flutter 应用中实现支付?

如何在 Flutter 中实现 Agora 云录制 api?

如何在 Flutter 中实现应用栏操作文本而不是操作图标?