Flutter搜索栏插件flutter_material_search_bar的使用

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

Flutter搜索栏插件flutter_material_search_bar的使用

Material Search Bar

Material Search Bar 是一个带有圆形展开动画的 Flutter 小部件,类似于 WhatsApp 的搜索栏。它受到了 WhatsApp SearchView 和 Android MaterialSearchView 的启发。

功能

  • 带有圆形展开动画的搜索栏
  • 支持自定义背景颜色、按钮等
  • 可以通过 MaterialSearchBarController 控制搜索栏的显示和隐藏

示例动图

使用方法

以下是一个完整的示例代码,展示了如何在项目中使用 flutter_material_search_bar 插件。

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_material_search_bar/flutter_material_search_bar.dart';

class MaterialSearchBarSample extends StatefulWidget {
  const MaterialSearchBarSample({super.key});

  [@override](/user/override)
  State<MaterialSearchBarSample> createState() => _MaterialSearchBarSampleState();
}

class _MaterialSearchBarSampleState extends State<MaterialSearchBarSample> {
  final List<String> _list = [];
  final List<String> _searchList = [];
  final debounce = Debounce(milliseconds: 800);
  final MaterialSearchBarController _controller = MaterialSearchBarController();
  final TextEditingController _searchQuery = TextEditingController();
  Color color = Colors.white;

  [@override](/user/override)
  void initState() {
    _getCityList();
    super.initState();
  }

  // 模拟获取城市列表数据
  void _getCityList() async {
    // 这里可以替换为实际的数据源,例如从网络请求或本地文件加载
    _list.addAll(['北京', '上海', '广州', '深圳', '杭州']);
    _searchList.addAll(_list);
    setState(() {});
  }

  Color getHintColor() {
    return color != Colors.white ? Colors.white : Colors.grey;
  }

  Color getIconColor() {
    return color != Colors.white ? Colors.white : Colors.black;
  }

  void _openDialog(String title, Widget content) {
    showDialog(
      context: context,
      builder: (_) {
        return AlertDialog(
          contentPadding: const EdgeInsets.all(18.0),
          title: Text(title),
          content: content,
          actions: [
            TextButton(
              onPressed: Navigator.of(context).pop,
              child: const Text('关闭'),
            ),
          ],
        );
      },
    );
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async {
        if (_controller.isSearchBarVisible) {
          _controller.toggleSearchBar();
          return false;
        } else {
          return true;
        }
      },
      child: Scaffold(
        appBar: MaterialSearchBar(
          controller: _controller,
          appBar: AppBar(
            title: const Text('MSB with AppBar'),
            actions: [
              IconButton(
                icon: const Icon(Icons.colorize),
                onPressed: () {
                  _openDialog(
                    '选择颜色',
                    MaterialColorPicker(
                      onColorChange: (Color newColor) {
                        setState(() {
                          color = newColor;
                        });
                      },
                      selectedColor: Colors.white,
                    ),
                  );
                },
              ),
              IconButton(
                icon: const Icon(Icons.search),
                onPressed: () {
                  _controller.toggleSearchBar();
                },
              ),
            ],
          ),
          color: color,
          alignment: Alignment.bottomRight,
          textField: TextField(
            onChanged: (text) {
              debounce.run(() {
                if (text.isNotEmpty) {
                  _searchList.clear();
                  for (var element in _list) {
                    if (element.toLowerCase().contains(text.toLowerCase())) {
                      _searchList.add(element);
                    }
                  }
                } else {
                  _searchList.clear();
                  _searchList.addAll(_list);
                }
                if (mounted) {
                  setState(() {});
                }
              });
            },
            controller: _searchQuery,
            cursorColor: Colors.black,
            style: const TextStyle(fontSize: 18.0, color: Colors.black),
            decoration: InputDecoration(
              border: InputBorder.none,
              focusedBorder: InputBorder.none,
              enabledBorder: InputBorder.none,
              errorBorder: InputBorder.none,
              disabledBorder: InputBorder.none,
              hintText: '搜索...',
              hintStyle: TextStyle(color: getHintColor()),
            ),
          ),
          backButton: IconButton(
            icon: Icon(Icons.arrow_back, color: getIconColor()),
            onPressed: () async {
              _searchQuery.text = '';
              _controller.toggleSearchBar();
            },
          ),
          clearButton: IconButton(
            icon: Icon(Icons.close, color: getIconColor()),
            onPressed: () {
              _searchQuery.text = '';
              _searchList.clear();
              _searchList.addAll(_list);
              if (mounted) {
                setState(() {});
              }
            },
          ),
        ),
        body: ListView.separated(
          itemBuilder: (context, index) {
            return ListTile(
              title: Text(_searchList[index]),
            );
          },
          separatorBuilder: (BuildContext context, int index) => const Divider(height: 1),
          itemCount: _searchList.length,
        ),
        floatingActionButton: FloatingActionButton(
          child: const Icon(Icons.close),
          onPressed: () {
            _searchQuery.text = '';
            _controller.toggleSearchBar();
          },
        ),
      ),
    );
  }
}

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

1 回复

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


当然,以下是一个关于如何使用 flutter_material_search_bar 插件的示例代码。这个插件提供了一个美观且功能丰富的搜索栏,非常适合在 Flutter 应用中实现搜索功能。

首先,确保在你的 pubspec.yaml 文件中添加 flutter_material_search_bar 依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_material_search_bar: ^0.6.1  # 请检查最新版本号

然后,运行 flutter pub get 来安装依赖。

接下来,在你的 Dart 文件中,你可以按照以下方式使用 flutter_material_search_bar

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final List<String> items = List<String>.generate(100, (i) => "Item $i");
  final SearchBarController _controller = SearchBarController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Material Search Bar Example'),
      ),
      body: Column(
        children: <Widget>[
          FlutterMaterialSearchBar(
            controller: _controller,
            hint: "Search...",
            suggestions: items,
            onChanged: (value) {
              setState(() {
                // 这里可以处理搜索输入的变化,比如过滤数据
                // 例如:_filteredItems = items.where((item) => item.contains(value)).toList();
              });
            },
            onSelected: (value) {
              // 用户选择一个搜索结果时的回调
              print("Selected: $value");
            },
            leading: Icon(Icons.search),
            trailing: Icon(Icons.clear),
            physical: true,
            searchBarStyle: SearchBarStyle(
              backgroundColor: Colors.white,
              inactiveColor: Colors.grey,
              activeColor: Colors.blue,
              iconColor: Colors.blueAccent,
              suggestionBoxDecoration: BoxDecoration(
                borderRadius: BorderRadius.circular(10),
                color: Colors.white,
              ),
              suggestionBoxShadow: [
                BoxShadow(
                  color: Colors.grey.withOpacity(0.5),
                  spreadRadius: 5,
                  blurRadius: 7,
                  offset: Offset(0, 3), // changes position of shadow
                ),
              ],
            ),
          ),
          Expanded(
            child: ListView.builder(
              itemCount: items.length,
              itemBuilder: (context, index) {
                // 这里可以显示过滤后的数据,或者原始数据
                return ListTile(
                  title: Text(items[index]),
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

在这个示例中,我们创建了一个包含搜索栏的页面。搜索栏使用了 FlutterMaterialSearchBar 组件,并设置了基本样式和回调函数。当用户输入搜索内容时,onChanged 回调函数会被触发,你可以在这里处理搜索输入的变化,比如过滤数据。当用户选择一个搜索结果时,onSelected 回调函数会被触发,你可以在这里处理用户选择的结果。

请注意,你需要根据实际需求调整 onChangedonSelected 回调中的逻辑,比如更新过滤后的数据列表。

回到顶部