Flutter搜索功能插件search_widget的使用

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

Flutter搜索功能插件search_widget的使用

在Flutter开发中,search_widget 是一个非常实用的插件,用于从数据列表中选择选项,并提供基于搜索文本的过滤功能。以下是该插件的使用方法及完整示例。


💻 安装

pubspec.yaml 文件的 dependencies: 部分添加以下行:

dependencies:
  search_widget: <最新版本>

运行 flutter pub get 来安装依赖。


❔ 使用

导入类

首先,导入 search_widget 包:

import 'package:search_widget/search_widget.dart';

添加搜索小部件

SearchWidget 接受多种参数,用于自定义其行为和外观。以下是主要参数的说明:

  1. dataList: 数据列表作为输入。
  2. onItemSelected: 获取选中的项目。如果项目被删除,则返回 null
  3. popupListItemBuilder: 返回一个用于显示弹出框中列表项的小部件。
  4. queryBuilder: 基于搜索查询过滤数据列表。
  5. selectedItemBuilder: 当用户从弹出列表中选择一个项目时,启用此选项。
  6. textFieldBuilder: 提供自定义的 TextField,可以接受 TextEditingControllerFocusNode 作为参数。

示例代码

以下是一个完整的实现示例:

SearchWidget<LeaderBoard>(
  dataList: list,
  hideSearchBoxWhenItemSelected: false,
  listContainerHeight: MediaQuery.of(context).size.height / 4,
  queryBuilder: (String query, List<LeaderBoard> list) {
    return list.where((LeaderBoard item) => 
      item.username.toLowerCase().contains(query.toLowerCase())
    ).toList();
  },
  popupListItemBuilder: (LeaderBoard item) {
    return PopupListItemWidget(item);
  },
  selectedItemBuilder: (LeaderBoard selectedItem, VoidCallback deleteSelectedItem) {
    return SelectedItemWidget(selectedItem, deleteSelectedItem);
  },
  // 自定义小部件
  noItemsFoundWidget: NoItemsFound(),
  textFieldBuilder: (TextEditingController controller, FocusNode focusNode) {
    return MyTextField(controller, focusNode);
  },
  onItemSelected: (item) {
    setState(() {
      _selectedItem = item;
    });
  },
)

示例代码详解

以下是一个完整的示例代码,展示了如何使用 search_widget 插件:

import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:search_widget/search_widget.dart';

// 设置桌面平台覆盖以避免异常。有关更多信息,请参见:
// https://flutter.dev/desktop#target-platform-override
void enablePlatformOverrideForDesktop() {
  if (!kIsWeb && (Platform.isMacOS || Platform.isWindows || Platform.isLinux)) {
    debugDefaultTargetPlatformOverride = TargetPlatform.fuchsia;
  }
}

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Search Widget',
      theme: ThemeData(
        primarySwatch: Colors.blueGrey,
      ),
      debugShowCheckedModeBanner: false,
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  [@override](/user/override)
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  List<LeaderBoard> list = [
    LeaderBoard("Flutter", 54),
    LeaderBoard("React", 22.5),
    LeaderBoard("Ionic", 24.7),
    LeaderBoard("Xamarin", 22.1),
  ];

  LeaderBoard _selectedItem;

  bool _show = true;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Search Widget"),
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.symmetric(vertical: 16),
        child: Column(
          children: <Widget>[
            const SizedBox(height: 16),
            if (_show)
              SearchWidget<LeaderBoard>(
                dataList: list,
                hideSearchBoxWhenItemSelected: false,
                listContainerHeight: MediaQuery.of(context).size.height / 4,
                queryBuilder: (query, list) {
                  return list
                      .where((item) => item.username.toLowerCase().contains(query.toLowerCase()))
                      .toList();
                },
                popupListItemBuilder: (item) {
                  return PopupListItemWidget(item);
                },
                selectedItemBuilder: (selectedItem, deleteSelectedItem) {
                  return SelectedItemWidget(selectedItem, deleteSelectedItem);
                },
                // 自定义小部件
                noItemsFoundWidget: NoItemsFound(),
                textFieldBuilder: (controller, focusNode) {
                  return MyTextField(controller, focusNode);
                },
                onItemSelected: (item) {
                  setState(() {
                    _selectedItem = item;
                  });
                },
              ),
            const SizedBox(height: 32),
            Text(
              "${_selectedItem != null ? _selectedItem.username : "No item selected"}",
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            _show = !_show;
          });
        },
        child: Icon(Icons.swap_horizontal_circle),
      ),
    );
  }
}

class LeaderBoard {
  LeaderBoard(this.username, this.score);

  final String username;
  final double score;
}

class SelectedItemWidget extends StatelessWidget {
  const SelectedItemWidget(this.selectedItem, this.deleteSelectedItem);

  final LeaderBoard selectedItem;
  final VoidCallback deleteSelectedItem;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.symmetric(vertical: 2, horizontal: 4),
      child: Row(
        children: <Widget>[
          Expanded(
            child: Padding(
              padding: const EdgeInsets.only(left: 16, right: 16, top: 8, bottom: 8),
              child: Text(
                selectedItem.username,
                style: const TextStyle(fontSize: 14),
              ),
            ),
          ),
          IconButton(
            icon: Icon(Icons.delete_outline, size: 22),
            color: Colors.grey[700],
            onPressed: deleteSelectedItem,
          ),
        ],
      ),
    );
  }
}

class MyTextField extends StatelessWidget {
  const MyTextField(this.controller, this.focusNode);

  final TextEditingController controller;
  final FocusNode focusNode;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
      child: TextField(
        controller: controller,
        focusNode: focusNode,
        style: TextStyle(fontSize: 16, color: Colors.grey[600]),
        decoration: InputDecoration(
          enabledBorder: const OutlineInputBorder(
            borderSide: BorderSide(color: Color(0x4437474F)),
          ),
          focusedBorder: OutlineInputBorder(
            borderSide: BorderSide(color: Theme.of(context).primaryColor),
          ),
          suffixIcon: Icon(Icons.search),
          border: InputBorder.none,
          hintText: "Search here...",
          contentPadding: const EdgeInsets.only(left: 16, right: 20, top: 14, bottom: 14),
        ),
      ),
    );
  }
}

class NoItemsFound extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        Icon(
          Icons.folder_open,
          size: 24,
          color: Colors.grey[900].withOpacity(0.7),
        ),
        const SizedBox(width: 10),
        Text(
          "No Items Found",
          style: TextStyle(
            fontSize: 16,
            color: Colors.grey[900].withOpacity(0.7),
          ),
        ),
      ],
    );
  }
}

class PopupListItemWidget extends StatelessWidget {
  const PopupListItemWidget(this.item);

  final LeaderBoard item;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(12),
      child: Text(
        item.username,
        style: const TextStyle(fontSize: 16),
      ),
    );
  }
}

更多关于Flutter搜索功能插件search_widget的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter搜索功能插件search_widget的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


search_widget 是一个用于在 Flutter 应用中实现搜索功能的插件。它提供了一个简单易用的搜索框,可以轻松地集成到你的应用中。以下是如何使用 search_widget 插件的基本步骤:

1. 添加依赖

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

dependencies:
  flutter:
    sdk: flutter
  search_widget: ^1.0.0

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

2. 导入包

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

import 'package:search_widget/search_widget.dart';

3. 使用 SearchWidget

SearchWidget 是一个可以显示搜索框并过滤列表的组件。以下是一个简单的示例,展示如何使用 SearchWidget

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

class SearchExample extends StatefulWidget {
  [@override](/user/override)
  _SearchExampleState createState() => _SearchExampleState();
}

class _SearchExampleState extends State<SearchExample> {
  List<String> _allItems = [
    "Apple",
    "Banana",
    "Cherry",
    "Date",
    "Elderberry",
    "Fig",
    "Grape",
    "Honeydew"
  ];

  String _selectedItem;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Search Widget Example'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            SearchWidget<String>(
              dataList: _allItems,
              hideSearchBoxWhenItemSelected: false,
              listContainerHeight: MediaQuery.of(context).size.height / 4,
              queryBuilder: (query, items) {
                return items
                    .where((item) => item.toLowerCase().contains(query.toLowerCase()))
                    .toList();
              },
              popupListItemBuilder: (item) {
                return PopupListItemWidget(item);
              },
              selectedItemBuilder: (selectedItem, deleteSelectedItem) {
                return SelectedItemWidget(selectedItem, deleteSelectedItem);
              },
              onItemSelected: (item) {
                setState(() {
                  _selectedItem = item;
                });
              },
            ),
            SizedBox(height: 20),
            Text(
              'Selected Item: ${_selectedItem ?? "None"}',
              style: TextStyle(fontSize: 18),
            ),
          ],
        ),
      ),
    );
  }
}

class PopupListItemWidget extends StatelessWidget {
  final String item;

  PopupListItemWidget(this.item);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(12),
      child: Text(
        item,
        style: TextStyle(fontSize: 16),
      ),
    );
  }
}

class SelectedItemWidget extends StatelessWidget {
  final String selectedItem;
  final VoidCallback deleteSelectedItem;

  SelectedItemWidget(this.selectedItem, this.deleteSelectedItem);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(12),
      child: Row(
        children: [
          Text(
            selectedItem,
            style: TextStyle(fontSize: 16),
          ),
          Spacer(),
          IconButton(
            icon: Icon(Icons.delete),
            onPressed: deleteSelectedItem,
          ),
        ],
      ),
    );
  }
}

void main() {
  runApp(MaterialApp(
    home: SearchExample(),
  ));
}
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!