当前位置 : 主页 > 手机开发 > android >

Android Flutter实现搜索的三种方式详解

来源:互联网 收集:自由互联 发布时间:2023-02-01
目录 示例 1 :使用搜索表单创建全屏模式 编码 示例 2:AppBar 内的搜索字段(最常见于娱乐应用程序) 编码 示例 3:搜索字段和 SliverAppBar 编码 结论 示例 1 :使用搜索表单创建全屏模
目录
  • 示例 1 :使用搜索表单创建全屏模式
    • 编码
  • 示例 2:AppBar 内的搜索字段(最常见于娱乐应用程序)
    • 编码
  • 示例 3:搜索字段和 SliverAppBar
    • 编码
  • 结论

    示例 1 :使用搜索表单创建全屏模式

    我们要构建的小应用程序有一个应用程序栏,右侧有一个搜索按钮。按下此按钮时,将出现一个全屏模式对话框。它不会突然跳出来,而是带有淡入淡出动画和幻灯片动画(从上到下)。在圆形搜索字段旁边,有一个取消按钮,可用于关闭模式。在搜索字段下方,我们会显示一些搜索历史记录(您可以添加其他内容,如建议、类别等)。

    编码

    我们通过定义一个扩展 ModalRoute 类的名为FullScreenSearchModal的类来创建完整模式。

    main.dart中的完整源代码及说明:

    // 大前端之旅
    // main.dart
    import 'package:flutter/material.dart';
    ​
    void main() => runApp(const MyApp());
    ​
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    ​
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          // remove the debug banner
          debugShowCheckedModeBanner: false,
          title: '大前端之旅',
          theme: ThemeData(
            primarySwatch: Colors.green,
          ),
          home: const KindaCodeDemo(),
        );
      }
    }
    ​
    // this class defines the full-screen search modal
    // by extending the ModalRoute class
    class FullScreenSearchModal extends ModalRoute {
      @override
      Duration get transitionDuration => const Duration(milliseconds: 500);
    ​
      @override
      bool get opaque => false;
    ​
      @override
      bool get barrierDismissible => false;
    ​
      @override
      Color get barrierColor => Colors.black.withOpacity(0.6);
    ​
      @override
      String? get barrierLabel => null;
    ​
      @override
      bool get maintainState => true;
    ​
      @override
      Widget buildPage(
        BuildContext context,
        Animation<double> animation,
        Animation<double> secondaryAnimation,
      ) {
        return Scaffold(
          body: SafeArea(
            child: Padding(
              padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 15),
              child: Column(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  // implement the search field
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Expanded(
                        child: TextField(
                          autofocus: true,
                          decoration: InputDecoration(
                            contentPadding: const EdgeInsets.symmetric(
                                vertical: 0, horizontal: 20),
                            filled: true,
                            fillColor: Colors.grey.shade300,
                            suffixIcon: const Icon(Icons.close),
                            hintText: 'Search 大前端之旅',
                            border: OutlineInputBorder(
                                borderSide: BorderSide.none,
                                borderRadius: BorderRadius.circular(30)),
                          ),
                        ),
                      ),
                      const SizedBox(
                        width: 10,
                      ),
                      // This button is used to close the search modal
                      TextButton(
                          onPressed: () => Navigator.of(context).pop(),
                          child: const Text('Cancel'))
                    ],
                  ),
    ​
                  // display other things like search history, suggestions, search results, etc.
                  const SizedBox(
                    height: 20,
                  ),
                  const Padding(
                    padding: EdgeInsets.only(left: 5),
                    child: Text('Recently Searched',
                        style:
                            TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
                  ),
                  const ListTile(
                    title: Text('Flutter tutorials'),
                    leading: Icon(Icons.search),
                    trailing: Icon(Icons.close),
                  ),
                  const ListTile(
                    title: Text('How to fry a chicken'),
                    leading: Icon(Icons.search),
                    trailing: Icon(Icons.close),
                  ),
                  const ListTile(
                    title: Text('大前端之旅'),
                    leading: Icon(Icons.search),
                    trailing: Icon(Icons.close),
                  ),
                  const ListTile(
                    title: Text('Goodbye World'),
                    leading: Icon(Icons.search),
                    trailing: Icon(Icons.close),
                  ),
                  const ListTile(
                    title: Text('Cute Puppies'),
                    leading: Icon(Icons.search),
                    trailing: Icon(Icons.close),
                  )
                ],
              ),
            ),
          ),
        );
      }
    ​
      // animations for the search modal
      @override
      Widget buildTransitions(BuildContext context, Animation<double> animation,
          Animation<double> secondaryAnimation, Widget child) {
        // add fade animation
        return FadeTransition(
          opacity: animation,
          // add slide animation
          child: SlideTransition(
            position: Tween<Offset>(
              begin: const Offset(0, -1),
              end: Offset.zero,
            ).animate(animation),
            child: child,
          ),
        );
      }
    }
    ​
    // This is the main screen of the application
    class KindaCodeDemo extends StatelessWidget {
      const KindaCodeDemo({Key? key}) : super(key: key);
    ​
      void _showModal(BuildContext context) {
        Navigator.of(context).push(FullScreenSearchModal());
      }
    ​
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: const Text('大前端之旅'), actions: [
            // this button is used to open the search modal
            IconButton(
              icon: const Icon(Icons.search),
              onPressed: () => _showModal(context),
            )
          ]),
          body: Container(),
        );
      }
    }

    示例 2:AppBar 内的搜索字段(最常见于娱乐应用程序)

    通常,许多娱乐应用程序(包括 Facebook、Youtube、Spotify 等大型应用程序)默认不显示搜索字段,而是显示搜索图标按钮。按下此按钮时,将显示搜索字段。

    我们要制作的演示应用程序包含 2 个屏幕(页面):HomePageSearchPage。用户可以通过点击搜索图标按钮从主页移动到搜索页面。搜索字段将通过使用SearchPage 的 AppBar的title参数来实现。

    让我们看看它是如何工作的:

    编码

    ./lib/main.dart中的完整源代码及说明:

    // main.dart
    import 'package:flutter/material.dart';
    ​
    void main() {
      runApp(const MyApp());
    }
    ​
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    ​
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
            // Remove the debug banner
            debugShowCheckedModeBanner: false,
            title: '大前端之旅',
            theme: ThemeData(
              primarySwatch: Colors.indigo,
            ),
            home: const HomePage());
      }
    }
    ​
    // Home Page
    class HomePage extends StatelessWidget {
      const HomePage({Key? key}) : super(key: key);
    ​
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('大前端之旅'),
            actions: [
              // Navigate to the Search Screen
              IconButton(
                  onPressed: () => Navigator.of(context)
                      .push(MaterialPageRoute(builder: (_) => const SearchPage())),
                  icon: const Icon(Icons.search))
            ],
          ),
        );
      }
    }
    ​
    // Search Page
    class SearchPage extends StatelessWidget {
      const SearchPage({Key? key}) : super(key: key);
    ​
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
              // The search area here
              title: Container(
            width: double.infinity,
            height: 40,
            decoration: BoxDecoration(
                color: Colors.white, borderRadius: BorderRadius.circular(5)),
            child: Center(
              child: TextField(
                decoration: InputDecoration(
                    prefixIcon: const Icon(Icons.search),
                    suffixIcon: IconButton(
                      icon: const Icon(Icons.clear),
                      onPressed: () {
                        /* Clear the search field */
                      },
                    ),
                    hintText: 'Search...',
                    border: InputBorder.none),
              ),
            ),
          )),
        );
      }
    }

    示例 3:搜索字段和 SliverAppBar

    广告搜索是许多电子商务应用程序最重要的功能之一,因此它们通常以最容易识别的方式显示搜索字段,并且从一开始就占用大量空间(亚马逊、Shopee 等)。

    编码

    // main.dart
    import 'package:flutter/material.dart';
    ​
    void main() {
      runApp(const MyApp());
    }
    ​
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    ​
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
            // Remove the debug banner
            debugShowCheckedModeBanner: false,
            title: '大前端之旅',
            theme: ThemeData(
              primarySwatch: Colors.deepPurple,
            ),
            home: const HomePage());
      }
    }
    ​
    class HomePage extends StatefulWidget {
      const HomePage({Key? key}) : super(key: key);
    ​
      @override
      State<HomePage> createState() => _HomePageState();
    }
    ​
    class _HomePageState extends State<HomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: CustomScrollView(
            slivers: [
              SliverAppBar(
                floating: true,
                pinned: true,
                snap: false,
                centerTitle: false,
                title: const Text('大前端之旅'),
                actions: [
                  IconButton(
                    icon: const Icon(Icons.shopping_cart),
                    onPressed: () {},
                  ),
                ],
                bottom: AppBar(
                  title: Container(
                    width: double.infinity,
                    height: 40,
                    color: Colors.white,
                    child: const Center(
                      child: TextField(
                        decoration: InputDecoration(
                            hintText: 'Search for something',
                            prefixIcon: Icon(Icons.search),
                            suffixIcon: Icon(Icons.camera_alt)),
                      ),
                    ),
                  ),
                ),
              ),
              // Other Sliver Widgets
              SliverList(
                delegate: SliverChildListDelegate([
                  const SizedBox(
                    height: 400,
                    child: Center(
                      child: Text(
                        'This is an awesome shopping platform',
                      ),
                    ),
                  ),
                  Container(
                    height: 1000,
                    color: Colors.pink,
                  ),
                ]),
              ),
            ],
          ),
        );
      }
    }

    结论

    您已经研究了在 Flutter 中实现全屏搜索框的端到端示例。这种搜索方式如今非常流行,您可以在许多大型应用程序和移动网站中注意到它。

    到此这篇关于Android Flutter实现搜索的三种方式详解的文章就介绍到这了,更多相关Android Flutter搜索内容请搜索自由互联以前的文章或继续浏览下面的相关文章希望大家以后多多支持自由互联!

    上一篇:Android内置的OkHttp用法介绍
    下一篇:没有了
    网友评论