flutter 之顶部搜索栏SearchDelegate

搜索栏是大部分APP都包括的组件,实际开发中需要这个搜索栏,网上阅读了一些资料后。实现flutter的搜索栏。Flutter为我们提供了这个组件SearchDelegate,先看一下效果图哦。
在这里插入图片描述
一、定义SearchDelegate

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);
  }
}

实现代码:


import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:ws/common/dao/expense_dao.dart';
import 'package:ws/model/expense_model.dart';
import 'package:ws/redux/ws_state.dart';
import 'package:ws/widget/ws_no_data.dart';

class ExpenseSearch extends SearchDelegate<String>{
  String searchHint = "请输入搜索内容...";
  var monthList = [
    "一月",
    "二月",
    "三月",
    "四月",
    "五月",
    "六月",
    "七月",
    "八月",
    "九月",
    "十月",
    "十一月",
    "十二月",
  ];

  var typeList = [
    "差旅费报销单",
    "一般费用报销单",
    "因公临时出国(境)支出表",
    "药费报销单",
    "合同付款审批表",
    "工资系统专用报销表",
  ];

  List<ExpenseList> items = new List<ExpenseList>();

  @override
  String get searchFieldLabel => searchHint;
  
  @override
  List<Widget> buildActions(BuildContext context) {
    // TODO: implement buildActions
    return [
      IconButton(
        icon: 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, null);
        } else {
          query = "";
          showSuggestions(context);
        }
      },
    );
  }

  @override
  Widget buildResults(BuildContext context) {

    return FutureBuilder(
      future: _loadData(),
      builder: (context, AsyncSnapshot snapshot) {
        return StoreBuilder<WSState>(
            builder: (context, store) {
              return ListView.builder(
                  physics: AlwaysScrollableScrollPhysics(),
                  itemCount: items?.length == 0 ? 1 : items.length,
                  itemBuilder: (BuildContext context, int index) {
                    if (items.length > 0) {
                      ExpenseList expenseList = items[index];
                      return ListTile(
                        title:Text(expenseList.title),
                        subtitle: Text(expenseList.content),
                      );
                    } else {
                      return NoData();
                    }
                  });

            });
      }
    );
    ///展示搜索结果

  }
  @override
  Widget buildSuggestions(BuildContext context) {
    return Container(
      margin: EdgeInsets.only(left: 16.0, right: 16.0),
      child: ListView(
        primary: false,
        shrinkWrap: true,
        children: <Widget>[
          SizedBox(height: 10.0),
          Text(
            "报销月份:",
            style: TextStyle(fontSize: 20),
          ),
          SizedBox(height: 10.0),
          Wrap(
            spacing: 8.0,
            runSpacing: 8.0,
            children: monthList.map((childNode) {
              return InkWell(
                child: new ClipRRect(
                  borderRadius: BorderRadius.circular(3.0),
                  child: Container(
                    padding: EdgeInsets.all(3.0),
                    color:Colors.grey,
                    child: Text(
                      childNode,
                      style: TextStyle(
                        fontSize: 16,
                        color: Colors.white,
                        shadows: [
                          BoxShadow(
                              color: Colors.grey, offset: Offset(0.2, 0.2))
                        ],
                      ),
                    ),
                  ),
                ),
                onTap: () {
                  _loadData();
                  Future.delayed( Duration(seconds: 2), () async {
                    searchHint = "";
                    query = childNode;
                    showResults(context);
                  });
                },
              );
            }).toList(),
          ),

          SizedBox(height: 10.0),
          Text(
            "报销类型:",
            style: TextStyle(fontSize: 18),
          ),
          SizedBox(height: 10.0),
          Wrap(
            spacing: 8.0,
            runSpacing: 8.0,
            children: typeList.map((childNode) {
              return InkWell(
                child: new ClipRRect(
                  borderRadius: BorderRadius.circular(3.0),
                  child: Container(
                    padding: EdgeInsets.all(3.0),
                    color:Colors.grey,
                    child: Text(
                      childNode,
                      style: TextStyle(
                        fontSize: 16,
                        color: Colors.white,
                        shadows: [
                          BoxShadow(
                              color: Colors.grey, offset: Offset(0.2, 0.2))
                        ],
                      ),
                    ),
                  ),
                ),
                onTap: () {
                  _loadData();
                  Future.delayed( Duration(seconds: 2), () async {
                    searchHint = "";
                    query = childNode;
                    showResults(context);
                  });
                },
              );
            }).toList(),
          ),
        ],
      ),
    );
  }

  _loadData() async {
    //网络加载
    var data = await ExpenseDao.getInitExpense(1, 20);
    Expense expense = Expense.fromJson(data);
    items=expense.list;
  }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值