繁体   English   中英

Flutter:带有来自数据库的动态内容的搜索栏

[英]Flutter: Search bar with dynamic content from a database

我目前正在开发一个 flutter 应用程序。 对于组系统,我需要创建组并向其中添加成员。 我希望创建组的用户在搜索字段中输入他想添加的用户的名称。 然后查看用户帐户是否存在。 整个事情应该动态地工作。 在键入名称时,结果应该会发生变化。 您可以想象它就像在 Instagram 或 Facebook 上搜索用户一样。

做这个的最好方式是什么? 我使用哪些小部件,我是否必须从数据库中获取所有注册用户,因为这对我来说看起来不太高效。

感谢您的回答!

编辑 1:对@LacticWhale 的回答

我设法从我的 model 对象列表中获取数据库中的所有用户。 所以我删除了名字和姓氏以将此列表传递给 UserSearchView class。但是当我想加载小部件时,它不起作用,因为某些断言失败了。 这是我的代码:

用户搜索视图 Class:

import 'package:flutter/material.dart';

class UserController extends ChangeNotifier {
  UserController({
    this.name = '',
  });

  String name;

  void changeName(String newName) {
    name = newName;

    notifyListeners();
  }
}

class UserSearchView extends StatefulWidget {
  const UserSearchView({
    required this.controller,
    required this.users,
    super.key,
  });

  final UserController controller;
  final List<String> users;

  @override
  State<StatefulWidget> createState() => _UserSearchViewState();
}

class _UserSearchViewState extends State<UserSearchView> {
  String _name = '';

  @override
  void initState() {
    widget.controller.addListener(() {
      setState(() {
        _name = widget.controller.name;
      });
    });
    super.initState();
  }

  @override
  void dispose() {
    widget.controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) => ListView.builder(
        itemBuilder: (context, index) => Text(widget.users
            .where((element) => element.contains(_name))
            .elementAt(index)),
        itemCount:
            widget.users.where((element) => element.contains(_name)).length,
      );
}

UI页面(部分):

TableRow(
              children: [
                TextFormField(
                  controller: textController,
                  onChanged: (value) => userController.changeName(value),
                  decoration: InputDecoration(
                      hintText: "Suchen",
                      border: OutlineInputBorder(
                          borderRadius: BorderRadius.circular(4)),
                      focusedBorder: OutlineInputBorder(
                        borderSide:
                            BorderSide(color: Theme.of(context).dividerColor),
                      ),
                      prefixIcon: const Icon(Icons.person),
                      suffixIcon: IconButton(
                        icon: const Icon(Icons.clear),
                        onPressed: () {
                          textController.text = '';
                          userController.changeName(textController.text);
                        },
                      )),
                ),
              ],
            ),
            TableRow(
              children: [
                UserSearchView(
                  controller: userController,
                  users: getUserNames(userList),
                ),
              ],
            ),

获取用户名 function:

List<String> getUserNames(List<User> userList) {
  List<String> userNames = List.empty();
  for (var user in userList) {
    userNames.add("${user.firstName} ${user.lastName}");
  }
  return userNames;
}

从数据库中获取所有用户。

使用搜索到的用户创建有状态小部件 (MySearchView)。

使用字段nameString ,默认为''?)创建 controller(扩展ChangeNotifier )添加方法 newName 并将新的 newName 分配给名称并调用方法 notifyListner

在您的 MySearchView 中,字段为 controller(您的控制器)

创建 State (_MySearchViewState) 通过将侦听器添加到 controller 并在构建中创建您的搜索列表来覆盖 initState

代码:

class MyController extends ChangeNotifier {
  MyController({
    this.name = '',
  });

  String name;

  void changeName(String newName) {
    name = newName;

    notifyListeners();
  }

}

class MySearchView extends StatefulWidget {
  const MySearchView({
    required this.controller,
    required this.users,  
    super.key, 
  });

  final MyController controller;
  final List<String> users;

  @override
  State<StatefulWidget> createState() => _MySearchViewState();

}

class _MySearchViewState extends State<MySearchView> {
  String _name = '';
  
  @override
  void initState() {
    widget.controller.addListener(() {
      setState(() {
        _name = widget.controller.name;
      });
    });
    super.initState();
  }
  

  @override
  void dispose() {
    widget.controller.dispose();
    super.dispose();
  }
  @override
  Widget build(BuildContext context) => ListView.builder(
    itemBuilder: (context, index) => Text(
      widget.users.where((element) => element.contains(_name)).elementAt(index)
    ),
    itemCount: widget.users.where((element) => element.contains(_name)).length,
  );

}

编辑:忘记在您的 TextField 中添加 onChange: (value) => controller.changeName(value)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM