首页 > 其他分享 >Flutter 自带的搜索组件

Flutter 自带的搜索组件

时间:2023-12-15 12:11:55浏览次数:27  
标签:return BuildContext override context child 组件 const 自带 Flutter

效果如下



官方需要重写四个关键方法

class searchBarDelegate extends SearchDelegate<String> {
 /*这个方法返回一个控件列表,显示为搜索框右边的图标按钮,这里设置为一个清除按钮,并且在搜索内容为空的时候显示建议搜索内容,使用的是showSuggestions(context)方法:*/
  @override
  List<Widget> buildActions(BuildContext context) {
    return null;
  }
/*这个方法返回一个控件,显示为搜索框左侧的按钮,一般设置为返回,这里返回一个具有动态效果的返回按钮:*/
  @override
  Widget buildLeading(BuildContext context) {
    return null;
  }

  @override
  Widget buildResults(BuildContext context) {
    return null;
  }
/*这个方法返回一个控件,显示为搜索内容区域的建议内容。*/
  @override
  Widget buildSuggestions(BuildContext context) {
    return null;
  }

/*这个方法返回一个主题,也就是可以自定义搜索界面的主题样式:*/
  @override
  ThemeData appBarTheme(BuildContext context) {
    // TODO: implement appBarTheme
    return super.appBarTheme(context);
  }
}

首页展示检索框

 Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Padding(
          padding: const EdgeInsets.only(top: 2, bottom: 2, left: 16),
          child: Container(
            height: 35,
            width: MediaQuery.of(context).size.width - 64,
            decoration: BoxDecoration(
                color: const Color.fromRGBO(230, 230, 230, 1.0),
                borderRadius: BorderRadius.circular(20)),
            child: InkWell(
              child: const Row(
                children: <Widget>[
                  Padding(
                      padding: EdgeInsets.only(left: 10, right: 10),
                      child: Icon(Icons.search, color: Colors.grey)),
                  Text(
                    "输入关键词查找片源",
                    style: TextStyle(color: Colors.grey, fontSize: 15),
                  )
                ],
              ),
              onTap: () {
                showSearch(context: context, delegate: SearchBarDelegate());
              },
            ),
          ),
        ),
        toolbarHeight: 45.sp,
        bottom: TabBar(
          controller: _tabController,
          tabs: tabs.map((e) => Tab(text: e)).toList(),
        ),
      ),

实现 SearchDelegate

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

class SearchBarDelegate extends SearchDelegate<String> {
  var nameList = ["完美世界", "西行记", "仙逆", "遮天", "圣墟", "斗罗大陆", "涉谷愤怒的海"];
  late bool flag;





  @override
  String get searchFieldLabel => '输入关键词查找片源';

  @override
  TextStyle get searchFieldStyle => TextStyle(fontSize: 14.0.sp);

  @override
  List<Widget>? buildActions(BuildContext context) {
    return [
      IconButton(
        icon: const Icon(Icons.clear),
        onPressed: () {
          query = "";
          showSuggestions(context);
        },
      )
    ];
  }

  @override
  Widget? buildLeading(BuildContext context) {
    return IconButton(
      icon: AnimatedIcon(
          icon: AnimatedIcons.menu_arrow, progress: transitionAnimation),
      onPressed: () {
        if (query.isEmpty) {
          close(context, '');
        } else {
          query = "";
          showSuggestions(context);
        }
      },
    );
  }

  @override
  Widget buildResults(BuildContext context) {
    for (int i = 0; i < nameList.length; i++) {
      if (query == nameList[i]) {
        flag = true;
        break;
      } else {
        flag = false;
      }
    }

    return flag == true
        ? Padding(
            padding: const EdgeInsets.all(16),
            child: InkWell(
              child: Text(query),
              onTap: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => TextScreen(s: query),
                  ),
                );
              },
            ))
        : const Center(
            child: Text("很抱歉,没有找到该搜索结果"),
          );
  }

  @override
  Widget buildSuggestions(BuildContext context) {
    final suggestionsList = query.isEmpty
        ? nameList
        : nameList.where((input) => input.startsWith(query)).toList();
    return ListView.builder(
        itemCount: suggestionsList.length,
        itemBuilder: (context, index) {
          return InkWell(
            child: ListTile(
              title: RichText(
                text: TextSpan(
                    text: suggestionsList[index].substring(0, query.length),
                    style: const TextStyle(
                        color: Colors.black, fontWeight: FontWeight.bold),
                    children: [
                      TextSpan(
                          text: suggestionsList[index].substring(query.length),
                          style: const TextStyle(color: Colors.grey))
                    ]),
              ),
            ),
            onTap: () {
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => TextScreen(s: suggestionsList[index]),
                ),
              );
            },
          );
        });
  }
}

class TextScreen extends StatelessWidget {
  final String s;

  const TextScreen({super.key, required this.s});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("搜索结果内容"),
      ),
      body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Center(
            child: Text(s),
          )),
    );
  }
}

为了和首页保持一样的效果需要修改源码

  • 修改文字和大小 提供重写方法
@override
  String get searchFieldLabel => '输入关键词查找片源';

  @override
  TextStyle get searchFieldStyle => TextStyle(fontSize: 14.0.sp);
  • 要在输入框之前加一个 检索的图标
  • ~/flutter/packages/flutter/lib/src/material/search.dart
// 导入icon
import 'package:flutter/material.dart';
// 修改源码  直接到文件末尾
return Semantics(
      explicitChildNodes: true,
      scopesRoute: true,
      namesRoute: true,
      label: routeName,
      child: Theme(
        data: theme,
        child: Scaffold(
          appBar: AppBar(
            leading: widget.delegate.buildLeading(context),
            title: TextField(
              controller: widget.delegate._queryTextController,
              focusNode: focusNode,
              style: widget.delegate.searchFieldStyle ?? theme.textTheme.titleLarge,
              textInputAction: widget.delegate.textInputAction,
              keyboardType: widget.delegate.keyboardType,
              onSubmitted: (String _) => widget.delegate.showResults(context),
              decoration: InputDecoration(
                  // 加这个位置
                  prefixIcon: Icon(Icons.search, color: Colors.grey),
                  hintText: searchFieldLabel
              ),
            ),
            flexibleSpace: widget.delegate.buildFlexibleSpace(context),
            actions: widget.delegate.buildActions(context),
            bottom: widget.delegate.buildBottom(context),
          ),
          body: AnimatedSwitcher(
            duration: const Duration(milliseconds: 300),
            child: body,
          ),
        ),
      ),
    );

标签:return,BuildContext,override,context,child,组件,const,自带,Flutter
From: https://www.cnblogs.com/guanchaoguo/p/17903101.html

相关文章

  • vue2子组件拷贝父组件传递的参数
    在Vue2中,父组件向子组件传递参数时,如果参数是对象或数组(即非基本数据类型),那么子组件可以直接修改这个参数,这会影响到父组件的数据。如果你想避免这种情况,你可以让子组件对父组件的传参进行深度拷贝。这样,子组件就可以自由修改拷贝后的参数,而不会影响到父组件的数据。这是一个例......
  • C++ Qt开发:ProgressBar进度条组件
    Qt是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍ProgressBar进度条组件的常用方法及灵活运用。ProgressBar(进度条)是在Qt中常用的用户界面组件之一......
  • 界面组件DevExpress VCL v23.2新功能预览 - 支持RAD Studio 12.0
    本文即将发布DevExpressVCL 下一个主要更新(v23.2),在之前的文章中(点击这里回顾>>)我们为大家介绍了新的工具提示、图表空间中的标签重叠等,本文将主要介绍DevExpressVCLv23.2中将支持的RADStudio12.0、增强的图像选择器、字体和自定义图标包等。新版即将发布,敬请期待哦~获取De......
  • Flutter开发之安卓打包,和获取签名相关信息,公钥值相关操作
    我们Flutter开发中,难免有些小朋友因需求要获取打包签名的一些相关信息,下面我们来讲一下怎么获取一生成签名文件我们打包安卓APK包需要先生成签名文件,需运行以下指令,生成签名文件keytool-genkey-v-keystoreGMT\_keystore.keystore-aliasGMT\_keystore-keyalgRSA-keysi......
  • Flutter技术基础
    技术基础语法主要是用dart,dart就是js和java的组合体,变量的声明,类,继承,构造函数,setget方法,以_开头的变量通常表示为私有变量。这意味着这个变量或者方法只能在当前Dart文件中访问,而不能被其他文件访问。一些集合包如map、list、set等等会用到的数据结构2.包管理:配置文件pubs......
  • 【活动回顾】Databend 云数仓与 Databend Playground 扩展组件介绍
    2023年12月7日,作为KubeSphere的合作伙伴,Databend荣幸地受邀参与了KubeSphere社区主办的云原生技术直播活动。本次活动的核心议题为「Databend云数仓与DatabendPlayground扩展组件介绍」,此次分享由DatabendLabs的研发工程师尚卓燃担任主讲嘉宾,向与会者呈现了一场......
  • kettle更新组件(insert_update)
    2种装载方式:全量装载和增量装载插入更新与表到表区别:表到表:只追加数据,不管表里重不重复插入更新:对比关键字段,更新所有数据(不会删除)创建数据流:需求:表输入组件只是将数据追加装载到表中,并不是我们想要的更新数据:如下:插入/更新匹配关键字id=id保留关键字的字段,用来匹......
  • C++ Qt开发:ComboBox下拉组合框组件
    Qt是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍ComboBox下拉组合框组件的常用方法及灵活运用。在Qt中,ComboBox(组合框)是一种常用的用户界面控件,它......
  • 推荐一个小而全的第三方登录开源组件
    大家好,我是Java陈序员。我们在企业开发中,常常需要实现登录功能,而有时候为了方便,就需要集成第三方平台的授权登录。如常见的微信登录、微博登录等,免去了用户注册步骤,提高了用户体验。为了业务考虑,我们有时候集成的不仅仅是一两个第三方平台,甚至更多。这就会大大的提高了工作量,那......
  • vue路由切换时内容组件的滚动条回到顶部
    vue路由切换时内容组件的滚动条回到顶部:https://blog.csdn.net/Macao7_W/article/details/125517519?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170252373016800185826420%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=......