Flutter应用内搜索插件flutter_spotlight_plus的使用

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

Flutter应用内搜索插件flutter_spotlight_plus的使用

插件介绍

flutter_spotlight_plus 是一个用于在Flutter应用中添加高亮搜索功能的插件。它可以帮助开发者创建类似于Spotlight这样的搜索界面,用户可以通过点击高亮区域来触发相应的操作。

示例代码

下面是一个完整的示例代码,展示了如何在Flutter应用中使用flutter_spotlight_plus插件实现搜索功能。

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Spotlight Plus Demo',
      debugShowCheckedModeBanner: false,
      home: MyHomePage(title: 'Flutter Spotlight Plus Tageting Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

  [@override](/user/override)
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  static final GlobalKey<_MyHomePageState> keySearch = GlobalKey<_MyHomePageState>();
  static final GlobalKey<_MyHomePageState> keySkipPrevious = GlobalKey<_MyHomePageState>();
  static final GlobalKey<_MyHomePageState> keyFastRewind = GlobalKey<_My HomePageState>();
  static final GlobalKey<_MyHomePageState> keyPlay = GlobalKey<_MyHomePageState>();
  static final GlobalKey<_MyHomePageState> keyFastForward = GlobalKey<_MyHomePageState>();
  static final GlobalKey<_MyHomePageState> keySkipNext = GlobalKey<_MyHomePageState>();
  static final GlobalKey<_MyHomePageState> keyFab = GlobalKey<_MyHomePageState>();

  List<List<dynamic>> targets = [
    [keySearch, "Search for videos"],
    [keySkipPrevious, "Skip to previous"],
    [keyFastRewind, "Rewind"],
    [keyPlay, "Play video"],
    [keyFastForward, "Forward"],
    [keySkipNext, "Skip to next"],
    [keyFab, "Add to favorites."],
  ];

  late Size _size;
  Offset? _center;
  double _radius = 50.0;
  bool _enabled = false;
  Widget? _description;

  int _index = 0;

  void spotlight(int index) {
    if (index >= targets.length) {
      index = 0;
      setState(() {
        _enabled = false;
      });
      return;
    }

    Rect? target = Spotlight.getRectFromKey(targets[index][0]);
    debugPrint("Rect : $target");
    debugPrint("Size : $_size");

    setState(() {
      _enabled = true;
      _center = Offset(target?.center.dx ?? 0, target?.center.dy ?? 0);
      _radius = Spotlight.calcRadius(target);
      _description = Container(
        alignment: Alignment.center,
        child: Text(
          targets[index][1] ?? '',
          style: ThemeData.dark().textTheme.caption.copyWith(color: Colors.white),
        ),
      );
    });
  }

  void _onTap() {
    _index++;
    spotlight(_index);
  }

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

    Future.delayed(Duration(seconds: 3)).then((value) {
      spotlight(0);
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    _size = MediaQuery.of(context).size;
    final height = MediaQuery.of(context).size.height - 56;

    return Spotlight(
      center: _center,
      radius: _radius,
      enabled: _enabled,
      description: _description,
      animation: true,
      onTap: _onTap,
      color: Color.fromRGBO(0, 0, 0, 0.8),
      child: Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
          actions: <Widget>[
            IconButton(
              key: keySearch,
              icon: Icon(Icons.search),
              tooltip: 'Open shopping cart',
              onPressed: () {
                debugPrint("onPressed");
              },
            ),
          ],
        ),
        body: SafeArea(
          child: Container(
            constraints: BoxConstraints.expand(),
            color: Colors.amber,
            child: Column(
              children: <Widget>[
                Expanded(
                  child: Container(
                      color: Colors.green,
                      alignment: Alignment.center,
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: <Widget>[
                          Image.asset(
                            'images/lake.jpg',
                            fit: BoxFit.cover,
                            height: height - 56,
                          ),
                          Padding(
                            padding: EdgeInsets.all(8.0),
                            child: Row(
                              mainAxisAlignment: MainAxisAlignment.center,
                              children: <Widget>[
                                IconButton(
                                  icon: Icon(Icons.skip_previous),
                                  onPressed: () {},
                                  key: keySkipPrevious,
                                ),
                                IconButton(
                                  icon: Icon(Icons.fast_rewind),
                                  onPressed: () {},
                                  key: keyFastRewind,
                                ),
                                IconButton(
                                  icon: Icon(Icons.play_arrow),
                                  onPressed: () {},
                                  key: keyPlay,
                                ),
                                IconButton(
                                  icon: Icon(Icons.fast_forward),
                                  onPressed: () {},
                                  key: keyFastForward,
                                ),
                                IconButton(
                                  icon: Icon(Icons.skip_next),
                                  onPressed: () {},
                                  key: keySkipNext,
                                ),
                              ],
                            ),
                          ),
                        ],
                      )),
                ),
              ],
            ),
          ),
        ),
        floatingActionButton: FloatingActionButton(
          key: keyFab,
          onPressed: () {
            debugPrint("onPressed");
          },
          child: Icon(Icons.favorite_border),
        ),
      ),
    );
  }
}

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

1 回复

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


当然,以下是一个关于如何在Flutter应用中使用flutter_spotlight_plus插件来实现应用内搜索功能的代码示例。flutter_spotlight_plus是一个强大的插件,允许开发者在应用内实现类似iOS Spotlight的搜索功能。

首先,确保你已经在pubspec.yaml文件中添加了flutter_spotlight_plus依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_spotlight_plus: ^x.y.z  # 请替换为最新版本号

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

接下来,在你的Flutter应用中,你可以按照以下步骤设置和使用flutter_spotlight_plus

  1. 导入插件

在你的Dart文件中导入flutter_spotlight_plus

import 'package:flutter_spotlight_plus/flutter_spotlight_plus.dart';
  1. 设置搜索项

你需要定义你想要搜索的数据。这里,我们假设你有一个简单的用户列表,每个用户都有一个nameemail属性。

class User {
  String name;
  String email;

  User({required this.name, required this.email});

  Map<String, dynamic> toMap() {
    return {
      'name': name,
      'email': email,
    };
  }
}
  1. 注册搜索项

在你的应用初始化时(例如在MyApp类的initState方法中),注册你想要搜索的数据。

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    List<User> users = [
      User(name: 'Alice', email: 'alice@example.com'),
      User(name: 'Bob', email: 'bob@example.com'),
      User(name: 'Charlie', email: 'charlie@example.com'),
    ];

    // 注册搜索项
    FlutterSpotlightPlus.registerSearchItems(
      searchItems: users.map((user) => {
        'identifier': user.name, // 唯一标识符
        'title': user.name, // 显示在搜索结果中的标题
        'subtitle': user.email, // 显示在搜索结果中的副标题
        'attributes': {
          'name': user.name,
          'email': user.email,
        },
      }).toList(),
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Spotlight Plus Example'),
        ),
        body: Center(
          child: Text('Swipe down to search'),
        ),
      ),
    );
  }
}
  1. 处理搜索结果

当用户执行搜索时(通常是通过向下滑动触发设备的搜索界面),你可以监听搜索结果并显示相应的内容。不过,flutter_spotlight_plus插件本身不直接处理搜索结果的显示,你需要根据搜索回调中的结果来更新你的UI。

这里是一个简单的监听搜索结果的示例(注意:实际使用时,你可能需要更复杂的逻辑来处理搜索结果):

@override
void initState() {
  super.initState();
  List<User> users = [
    User(name: 'Alice', email: 'alice@example.com'),
    User(name: 'Bob', email: 'bob@example.com'),
    User(name: 'Charlie', email: 'charlie@example.com'),
  ];

  // 注册搜索项
  FlutterSpotlightPlus.registerSearchItems(
    searchItems: users.map((user) => {
      'identifier': user.name,
      'title': user.name,
      'subtitle': user.email,
      'attributes': {
        'name': user.name,
        'email': user.email,
      },
    }).toList(),
  );

  // 监听搜索结果
  FlutterSpotlightPlus.onSearchResults((results) {
    // 处理搜索结果
    // results 是一个包含搜索匹配项的列表,每个项是一个 Map
    print('Search results: $results');

    // 根据搜索结果更新你的UI(这里省略了具体的UI更新逻辑)
  });
}

请注意,flutter_spotlight_plus的具体用法和API可能会随着版本的更新而变化,因此建议查阅最新的官方文档以获取最准确的信息。此外,由于搜索结果的处理和UI更新逻辑可能相对复杂,上述代码仅提供了一个基本的框架,你需要根据实际需求进行扩展和完善。

回到顶部