提示

已将代码上传至gitee,后续会继续更新学习封装的一些组件:
flutter练习

实现效果

请添加图片描述

实现过程

  • 1.封装菜单子项MenuItem
/// @author longzipeng
/// @创建时间:2022/3/30
/// 通用菜单项model
class MenuItem {
  String label; // 显示的文本
  dynamic value; // 选中的值
  bool checked; // 是否选中

  MenuItem({this.label = '', this.value, this.checked = false});
}
  • 2.基于弹出菜单组件封装下拉菜单:
import 'package:csdn_flutter_demo/models/menu_item.dart';
import 'package:flutter/material.dart';

/// @author longzipeng
/// @创建时间:2022/3/30
/// 弹出菜单按钮组件
class SelectWidget extends StatefulWidget {
  final List<MenuItem> items; // 显示的内容
  final dynamic value; // 当前选中的值
  final String? title; // 选择框前的标题
  final String tooltip; // 提示语
  final ValueChanged<dynamic>? valueChanged; // 选中数据的回调事件
  const SelectWidget(
      {Key? key,
      this.items = const [],
      this.value,
      this.valueChanged,
      this.title,
      this.tooltip = "点击选择"})
      : super(key: key);

  @override
  State<SelectWidget> createState() => _SelectWidgetState();
}

class _SelectWidgetState extends State<SelectWidget> {
  String label = '请选择';
  bool isExpand = false; // 是否展开下拉按钮
  dynamic currentValue; // 此时的值

  @override
  void initState() {
    currentValue = widget.value;
    super.initState();
  }

  /// 根据当前的value处理当前文本显示
  void initTitle() {
    if (currentValue != null) {
      // 有值查值
      for (MenuItem item in widget.items) {
        if (item.value == currentValue) {
          label = item.label;
          break;
        }
      }
    } else {
      // 没值默认取第一个
      if (widget.items.isNotEmpty) {
        label = widget.items[0].label;
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    initTitle();
    return Wrap(
      children: [
        if (widget.title != null)
          Text(widget.title!, style: TextStyle(fontSize: 18)),
        PopupMenuButton<String>(
          // initialValue: currentValue,
          tooltip: widget.tooltip,
          offset: Offset(25, 30),
          enableFeedback: true,
          child: Listener(
            // 使用listener事件能够继续传递
            onPointerDown: (event) {
              setState(() {
                isExpand = !isExpand;
              });
            },
            child: Wrap(
              children: [
                Text(
                  label,
                  style: TextStyle(fontSize: 18),
                ),
                isExpand
                    ? const Icon(Icons.arrow_drop_up)
                    : const Icon(Icons.arrow_drop_down)
              ],
            ),
          ),
          onSelected: (value) {
            widget.valueChanged?.call(value);
            setState(() {
              currentValue = value;
              isExpand = !isExpand;
            });
          },
          onCanceled: () {
            // 取消展开
            setState(() {
              isExpand = false;
            });
          },
          itemBuilder: (context) {
            return widget.items
                .map(
                  (item) => item.value == currentValue
                      ? PopupMenuItem<String>(
                          value: item.value,
                          child: Text(
                            item.label,
                            style: TextStyle(
                                color: Theme.of(context).primaryColor),
                          ),
                        )
                      : PopupMenuItem<String>(
                          value: item.value,
                          child: Text(item.label),
                        ),
                )
                .toList();
          },
        )
      ],
    );
  }
}

测试

import 'package:csdn_flutter_demo/models/menu_item.dart';
import 'package:csdn_flutter_demo/pages/common/common_appbar.dart';
import 'package:csdn_flutter_demo/widgets/select_widget.dart';
import 'package:flutter/material.dart';

/// @author longzipeng
/// @创建时间:2022/3/30
/// 下拉选择demo
class SelectDemoPage extends StatefulWidget {
  const SelectDemoPage({Key? key}) : super(key: key);

  @override
  State<SelectDemoPage> createState() => _SelectDemoPageState();
}

class _SelectDemoPageState extends State<SelectDemoPage> {
  String value = "1";

  /// 下拉选择值改变
  selectChange(value) {
    print("值改变了:$value");
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: CommonAppbar(
        title: "下拉菜单演示",
      ),
      body: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          SelectWidget(
            items: [
              MenuItem(label: "张飞", value: '1'),
              MenuItem(label: "关羽", value: '2'),
              MenuItem(label: "刘备", value: '3'),
              MenuItem(label: "圆头儿子", value: '4'),
              MenuItem(label: "大头爸爸", value: '5'),
              MenuItem(label: "小头妈妈", value: '6'),
            ],
            value: value,
            valueChanged: selectChange,
          ),
        ],
      ),
    );
  }
}

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐