flutter封装一个筛选框

效果图:

这个函数接收两个参数:

第一个参数context上下文

第二个参数contentMap(这个参数主要作用就是接收你需要搜索的东西,生成输入框或者选择器或者日期选择 这里暂时只有这几种,后期有需要可以在下面 “循环生成输入框” 的方法中增加判断生成其他类型的控件)

※在封装的时候我是另外创建的一个文件utils.dart,然后直接写方法所以就没有状态,就意味着在里面无法使用setState方法,(就算不是另外创建的一个文件,在原来的页面中创建这个方法虽然有setState方法但是,由于使用了"showDialog"就相当于是重新打开了一个页面,你在setState也是没有效果的,就相当于你拿前朝的剑来斩本朝的官,这不现实啊),解决办法就是在需要刷新状态的组件外面再套一个有状态的组件不就行了吗StatefulBuilder,但是定义状态不能定义到StatefulBuilder里面去,因为状态一更新重新执行一遍StatefulBuilder里面的代码,所以定义的状态又变回去了,然后我就直接将date1定义到StatefulBuilder外面然后就好使了,从昨天下午一直研究到今天早上,终究还是有收获的嘛!!!

import 'package:find_dropdown/find_dropdown.dart';// 搜索框使用到的插件find_dropdown: ^1.0.0

funshowAlertDialog(BuildContext context, contentMap) async {
  // 当前时间
  DateTime _nowDate = DateTime.now();

  bool flag = false;
  //设置按钮
  Widget cancelButton = Container(
    margin: EdgeInsets.only(right: 10),
    child: InkWell(
      child: Text("取消"),
      onTap: () {
        Navigator.pop(context);
      },
    ),
  );
  Widget continueButton = Container(
    child: InkWell(
      child: Text(
        "搜索",
        style: TextStyle(color: Colors.blue),
      ),
      onTap: () {
        flag = true;
        Navigator.of(context).pop('123456');
      },
    ),
  );

  // 循环生成输入框
  List<Widget> _funCreateWidget() {
    List<Widget> widgetList = [];
    contentMap.forEach((item) {
      if (item['type'] == 'textFile') {
        widgetList.add(
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Text(item['key']),
              Container(
                margin: EdgeInsets.only(left: 5, bottom: 5),
                width: 183,
                child: TextField(
                  decoration: InputDecoration(
                    border: InputBorder.none,
                    hintText: '请输入',
                    hintStyle: TextStyle(fontSize: 16.0),
                  ),
                  onChanged: (e) {
                    item['words'] = e;
                  },
                ),
              ),
            ],
          ),
        );
      } else if(item['type']=='date'){
        String date1 = '请选择';
                widgetList.add(StatefulBuilder(builder: (context, setstA) {
                  print('重新渲染');
                  return Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Text(item['key']),
                      Container(
                          margin: EdgeInsets.fromLTRB(5,11.5,5,11.5),
                          width: 180,
                          // decoration: BoxDecoration(border: Border.all(color: Colors.grey,width: 1)),
                          child: InkWell(
                            child: Row(
                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
                              children: [
                                Text('$date1'),
                                Icon(
                                  Icons.arrow_forward_ios_rounded,
                                  color: Colors.grey,
                                )
                              ],
                            ),
                            onTap: () async {
                              var res = await showDatePicker(
                                // 上下文环境
                                context: context,
                                // 初始化时间
                                initialDate: _nowDate,
                                // 最早时间
                                firstDate: DateTime(1980),
                                // 最晚时间
                                lastDate: DateTime(2100),
                              );
                              print('选择日期');
                              print(res.toString());
                              item['nm'] = res.toString().substring(0, 10);
                              setstA(() {
                                date1 = res.toString().substring(0, 10);
                              });

                              print(item);
                            },
                          )),
                    ],
                  );
                }));
      } 
      else {
        List<String> dropList = [];
        item['dropDownList'].forEach((item) {
          dropList.add(item['subCodeNm']);
        });

        widgetList.add(
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Text(item['key']),
              Container(
                margin: EdgeInsets.only(left: 5, bottom: 5),
                width: 183,
                child: FindDropdown(
                  searchHint: '搜索',
                  items: dropList,
                  onChanged: (e) {
                    for (var itema in item['dropDownList']) {
                      if (itema['subCodeNm'] == e) {
                        // print(itema);
                        item['nm'] = itema['subCodeNm'];
                        item['code'] = itema['subCode'];
                        // print(item.toString());
                        return;
                      }
                    }
                  },
                  selectedItem: "请选择",
                ),
              ),
            ],
          ),
        );
      }
    });
    return widgetList;
  }

  //设置对话框
  AlertDialog alert = AlertDialog(
    title: Text("筛选"),
    contentPadding: EdgeInsets.fromLTRB(10, 10, 10, 10),
    content: Container(
      height: 60.0 * contentMap.length,
      child: Column(
        children: _funCreateWidget(),
      ),
    ),
    actions: [
      cancelButton,
      continueButton,
    ],
  );

  //显示对话框
  return await showDialog(
    context: context,
    builder: (BuildContext context) {
      return alert;
    },
  ).then((value) {
    print('对话框即将关闭');
    if (flag) {
      // 判断是不是点击可了搜索
      return contentMap; // 点击了搜索就返回内容
    } else {
      return ''; // 点击了取消就返回空
    }
  });
}

调用筛选:

只需要在组件的点击事件中调用此方法就能弹出筛选框

例:

IconButton(
    icon: const Icon(Icons.filter_alt_outlined),
    tooltip: '筛选',
    onPressed: () {
        funshowAlertDialog(context, [
            {
                'key': '调拨方',
                'type': 'dropDown',
                'nm': '请选择',
                'code': '',
                'dropDownList': [
                    {'subCodeNm': '1', 'subCode': '1'},
                    {'subCodeNm': '2', 'subCode': '2'},
                    {'subCodeNm': '3', 'subCode': '3'}
                ]// 注意这里的对象的属性必须叫"subCodeNm"和"subCode",如果你看懂了上面的封装,如果想改属性名那么这两个地方的属性名必须一致
            },
            {
                'key': '调拨日期',
                'type': 'date',
                'nm': '',
            },
            {
                'key': '船名',
                'type': 'textFile',
                'words':'',
            },
            
        ]).then((res) {
            // 这里的res就是你传入的数据选择或者输入之后的结果
            // 如果type是"dropDown"那么该对象的"nm"属性对应的值就是下拉框选择的"subCodeNm"的值,该对象的"code"属性对应的值就是下拉框选择的"subCode"的值
            // 如果type是date那么该对象的"nm"属性就是你选择的日期
            // 如果type是textFile那么该对象的"words"属性就是你所输入的值
            print('*************');
            print(res);
            print('*************');

        });
    },
)
    
好的,我可以为您提供一个简单的自定义列表块封装示例。以下是一个基本的代码示例: ```dart import 'package:flutter/material.dart'; class CustomListItem extends StatelessWidget { CustomListItem({ this.title, this.subtitle, this.thumbnail, }); final String title; final String subtitle; final Widget thumbnail; @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.symmetric(vertical: 10.0), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ thumbnail, Expanded( child: Padding( padding: const EdgeInsets.fromLTRB(20.0, 0.0, 2.0, 0.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Text( title, style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 18.0, ), ), const Padding(padding: EdgeInsets.symmetric(vertical: 2.0)), Text( subtitle, style: const TextStyle(fontSize: 16.0), ), ], ), ), ) ], ), ); } } ``` 您可以在需要使用自定义的列表块的地方使用此小部件。例如,以下是一个使用此自定义列表块的示例: ```dart class MyCustomList extends StatelessWidget { @override Widget build(BuildContext context) { return ListView( padding: const EdgeInsets.all(10.0), children: <Widget>[ CustomListItem( title: 'Flutter', subtitle: 'Google’s UI toolkit for building beautiful, natively compiled applications for mobile, web, and desktop from a single codebase', thumbnail: Container( decoration: const BoxDecoration(color: Colors.blue), ), ), CustomListItem( title: 'Dart', subtitle: 'A client-optimized language for fast apps on any platform', thumbnail: Container( decoration: const BoxDecoration(color: Colors.green), ), ), CustomListItem( title: 'Material Design', subtitle: 'A design system for building beautiful, natively compiled applications for mobile, web, and desktop', thumbnail: Container( decoration: const BoxDecoration(color: Colors.orange), ), ), ], ); } } ``` 这个示例中,我们使用 `MyCustomList` 小部件来构建一个包含三个自定义列表块的列表。每个列表块都包含一个缩略图、标题和子标题。请注意,我们可以在自定义列表块中使用任何小部件,以便根据自己的需求进行自定义。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值