【问题标题】:Flutter: How to search from FutureBuilder ListviewFlutter:如何从 FutureBuilder 列表视图中搜索
【发布时间】:2023-03-04 23:31:01
【问题描述】:

我是 Flutter 的新手,正在尝试完成我的应用程序的最后剩余部分。我正在使用 Firebase 实时数据库来存储员工数据并使用 ListView.builder 列出它。我能够显示列表中的所有信息,但我想实现搜索栏。我开始将它放在控制器中并在终端中显示,但不确定如何正确实现它以过滤数据。

我将传递我的完整代码,但删除 firebase 数据库,因为它现在开放进行测试。

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';
import 'directory_details_screen.dart';

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

  @override
  _DirectoryState createState() => _DirectoryState();
}

class _DirectoryState extends State<Directory> {
  TextEditingController _searchController = TextEditingController();

  Future getEmpData() async {
    var response = await http.get(Uri.parse(
        'FIREBASE REMOVED'));
    var jsonData = jsonDecode(response.body);
    List<Employee> employees = [];

    for (var e in jsonData) {
      Employee employee = Employee(
          e["displayName"],
          e["department"],
          e["jobTitle"],
          e["mobilePhone"],
          e["workEmail"],
          e["photoUrl"],
          e["workPhoneExtension"]);
      employees.add(employee);
    }
    print(employees.length);
    return employees;
  }


  @override
  void initState() {
    super.initState();
    _searchController.addListener(_onSearchChanged);
  }

  @override
  void dispose() {
    _searchController.removeListener(_onSearchChanged);
    _searchController.dispose();
    super.dispose();
  }

  _onSearchChanged() {
    print(_searchController.text);
  }

  String searchString = "";

  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        mainAxisSize: MainAxisSize.max,
        mainAxisAlignment: MainAxisAlignment.start,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          SizedBox(height: 10),
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 15.0),
            child: TextField(
              onChanged: (value) {
                setState(() {
                  searchString = value;
                });
              },
              controller: _searchController,
              decoration: InputDecoration(
                labelText: 'Search',
                suffixIcon: Icon(Icons.search),
              ),
            ),
          ),
          SizedBox(height: 10),
          Expanded(
            child: FutureBuilder(
              future: getEmpData(),
              builder: (context, AsyncSnapshot snapshot) {
                if (snapshot.data == null) {
                  return Container(
                    child: Center(
                      child: CircularProgressIndicator(),
                    ),
                  );
                } else
                  return ListView.builder(
                      itemCount: snapshot.data!.length,
                      itemBuilder: (context, i) {
                        return Card(
                          child: ListTile(
                            leading: CircleAvatar(
                              backgroundImage: NetworkImage(
                                snapshot.data[i].photoUrl
                              ),
                            ),
                            //leading: Icon(Icons.account_circle),
                            isThreeLine: true,
                            title: Text(snapshot.data[i].displayName,
                                style: TextStyle(fontWeight: FontWeight.bold)),
                            subtitle: Text("Department: " +
                                snapshot.data[i].department +
                                "\n" +
                                "Title: " +
                                snapshot.data[i].jobTitle),
                            onTap: () {
                              Navigator.of(context).push(MaterialPageRoute(
                                  builder: (context) => EmployeeDetails(
                                      employee: snapshot.data[i])));
                            },
                          ),
                        );
                      });
              },
            ),
          ),
        ],
      ),
    );
  }
}

class Employee {
  final String displayName,
      department,
      jobTitle,
      mobilePhone,
      workEmail,
      photoUrl,
      workPhoneExtension;
  Employee(this.displayName, this.department, this.jobTitle, this.mobilePhone,
      this.workEmail, this.photoUrl, this.workPhoneExtension);
}

【问题讨论】:

    标签: firebase flutter listview search


    【解决方案1】:

    你可以试试这样的:

    ...
    } else {
    final result = _search(snapshot.data);
    
      return ListView.builder(
          itemCount: result.length,
          itemBuilder: (context, i) {
            return Card(
              child: ListTile(
                leading: CircleAvatar(
                  backgroundImage: NetworkImage(
                      result[i].photoUrl
                  ),
                ),
                //leading: Icon(Icons.account_circle),
                isThreeLine: true,
                title: Text(result[i].displayName,
                    style: TextStyle(fontWeight: FontWeight.bold)),
                subtitle: Text("Department: " +
                    result[i].department +
                    "\n" +
                    "Title: " +
                    result[i].jobTitle),
                onTap: () {
                  Navigator.of(context).push(MaterialPageRoute(
                      builder: (context) =>
                          EmployeeDetails(
                              employee: result[i])));
                },
              ),
            );
          });
        ...
    
    

    和类似的搜索方法

    List<Employee> _search(List<Employee>? employee) {
      if(searchString?.isNotEmpty == true) {
        //search logic what you want
        return employee?.where((element) => element.department.contains(searchString))
            .toList() ?? <Employee>[];
      }
      
      return employee ?? <Employee>[];
    }
    

    【讨论】:

    • 结果列表取决于您的 searchString 值。因此,当您更改 searchString 时,列表将重建并仅显示搜索到的元素。当您将 searchString 设置为空值时,结果列表将包含来自 snapshot.data 的所有元素。或者,也许您想直接在 Firebase 实时数据库中搜索? @BryanS
    猜你喜欢
    • 1970-01-01
    • 2017-08-29
    • 1970-01-01
    • 1970-01-01
    • 2021-03-24
    • 2021-03-09
    • 2019-02-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多