日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無先后,達(dá)者為師

網(wǎng)站首頁 編程語言 正文

Android?Flutter實(shí)現(xiàn)搜索的三種方式詳解_Android

作者:大前端之旅 ? 更新時(shí)間: 2022-10-02 編程語言

示例 1 :使用搜索表單創(chuàng)建全屏模式

我們要構(gòu)建的小應(yīng)用程序有一個(gè)應(yīng)用程序欄,右側(cè)有一個(gè)搜索按鈕。按下此按鈕時(shí),將出現(xiàn)一個(gè)全屏模式對(duì)話框。它不會(huì)突然跳出來,而是帶有淡入淡出動(dòng)畫和幻燈片動(dòng)畫(從上到下)。在圓形搜索字段旁邊,有一個(gè)取消按鈕,可用于關(guān)閉模式。在搜索字段下方,我們會(huì)顯示一些搜索歷史記錄(您可以添加其他內(nèi)容,如建議、類別等)。

編碼

我們通過定義一個(gè)擴(kuò)展 ModalRoute 類的名為FullScreenSearchModal的類來創(chuàng)建完整模式。

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 內(nèi)的搜索字段(最常見于娛樂應(yīng)用程序)

通常,許多娛樂應(yīng)用程序(包括 Facebook、Youtube、Spotify 等大型應(yīng)用程序)默認(rèn)不顯示搜索字段,而是顯示搜索圖標(biāo)按鈕。按下此按鈕時(shí),將顯示搜索字段。

我們要制作的演示應(yīng)用程序包含 2 個(gè)屏幕(頁面):HomePageSearchPage。用戶可以通過點(diǎn)擊搜索圖標(biāo)按鈕從主頁移動(dòng)到搜索頁面。搜索字段將通過使用SearchPage 的 AppBar的title參數(shù)來實(shí)現(xiàn)。

讓我們看看它是如何工作的:

編碼

./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

廣告搜索是許多電子商務(wù)應(yīng)用程序最重要的功能之一,因此它們通常以最容易識(shí)別的方式顯示搜索字段,并且從一開始就占用大量空間(亞馬遜、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,
              ),
            ]),
          ),
        ],
      ),
    );
  }
}

結(jié)論

您已經(jīng)研究了在 Flutter 中實(shí)現(xiàn)全屏搜索框的端到端示例。這種搜索方式如今非常流行,您可以在許多大型應(yīng)用程序和移動(dòng)網(wǎng)站中注意到它。

原文鏈接:https://juejin.cn/post/7129292610295824421

欄目分類
最近更新