简体   繁体   English

我如何在颤振中创建这样的下拉列表

[英]How i can create dropdown like this in flutter

Hey guys I'm working on some project and need to create a custom dropdown, like this嘿伙计们,我正在做一些项目,需要创建一个自定义下拉列表,就像这样

在此处输入图片说明

在此处输入图片说明

I am able to make that here is the code, the code is messy but I will refactor it once I make it work.我能够做到这是代码,代码很乱,但一旦我让它工作,我就会重构它。 Or if you have some other way how I can accomplish this I'm open to suggestions.或者,如果您有其他方法可以实现这一点,我愿意接受建议。

  GlobalKey? actionKey = GlobalKey();

 List<String> picked = [];

  List<IconData> icons = [
    Icons.blur_circular_outlined,
    Icons.sports_basketball,
    Icons.sports_baseball_sharp,
    Icons.sports_tennis_rounded,
    Icons.people,
  ];
  List<String> sports = [
    "Fudbal",
    "Kosarka",
    "Tenis",
    "Stoni tenis",
    "Kuglanje"
  ];
  List<int> ints = [0, 1, 2, 3, 4];

  List<bool> booles = [false, false, false, false, false];
  OverlayEntry? overlayEntry;
  var position;
  double? y;
  double? x;
  void findDropdownData() {
    RenderBox renderBox =
        actionKey!.currentContext!.findRenderObject() as RenderBox;
    position = renderBox.localToGlobal(Offset.zero);
    y = position!.dy;
    x = position!.dx;
  }

  OverlayEntry _overlayEntryBuilder() {
    return OverlayEntry(
      builder: (context) {
        return Positioned(
          // top: position,
          left: 16.w,
          right: 16.w,
          child: Material(
            child: dropdownExpanded(),
          ),
        );
      },
    );
  }

  Widget buildRows(i) {
    return Padding(
      padding: EdgeInsets.symmetric(horizontal: 17.w, vertical: 15.h),
      child: Row(
        children: [
          SizedBox(
            height: 24.h,
            width: 24.w,
            child: Checkbox(
              activeColor: style.purpleMain,
              value: booles[i],
              shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(4)),
              onChanged: (value) {
                setState(() {
                  booles[i] = value!;
                  booles[i] == true
                      ? picked.add(sports[i])
                      : picked.remove(sports[i]);
                });
              },
            ),
          ),
          SizedBox(
            width: 10.w,
          ),
          Text(
            sports[i],
            style: TextStyle(
              color: booles[i] == true ? style.purpleMain : Colors.grey,
            ),
          ),
          const Spacer(),
          Icon(
            icons[i],
            color: booles[i] == true ? style.purpleMain : Colors.grey,
            size: 15,
          ),
        ],
      ),
    );
  }

  Widget dropdown() {
    return GestureDetector(
      key: actionKey,
      onTap: () {
        setState(() {
          isPressed = !isPressed;
        });
        if (isPressed == false) {
          overlayEntry = _overlayEntryBuilder();
          Overlay.of(context)!.insert(overlayEntry!);
        }
      },
      child: Container(
        width: double.infinity,
        height: 50.h,
        decoration: BoxDecoration(
          border: Border.all(color: style.e8e8e8),
          borderRadius: BorderRadius.circular(8),
        ),
        padding: EdgeInsets.only(left: 16.w, right: 13.w),
        child: Row(
          children: [
            picked.isEmpty ? pickedEmpty() : pickedNotEmpty(),
            const Spacer(),
            const Icon(
              Icons.arrow_drop_down,
              color: style.bdbdbd,
            ),
          ],
        ),
      ),
    );
  }

  Widget pickedEmpty() {
    return Text(
      "Možete obeležiti više aktivnosti",
      style: TextStyle(
        fontSize: 16.sp,
        color: style.bdbdbd,
        fontWeight: FontWeight.w400,
      ),
    );
  }

  Widget pickedNotEmpty() {
    List<Widget> list = <Widget>[];
    for (var i = 0; i < picked.length; i++) {
      list.add(
        Padding(
          padding: EdgeInsets.only(right: 5.w),
          child: Text(
            picked[i],
            style: TextStyle(
              fontSize: 16.sp,
              color: style.bdbdbd,
              fontWeight: FontWeight.w400,
            ),
          ),
        ),
      );
    }
    return Row(children: list);
  }

  Widget dropdownExpanded() {
    return Container(
      decoration: BoxDecoration(
        color: Colors.white,
        border: Border.all(color: style.purpleMain),
        borderRadius: BorderRadius.circular(8),
      ),
      child: Column(
        children: [
          GestureDetector(
            onTap: () {
              setState(() {
                isPressed = !isPressed;
              });
              overlayEntry?.remove();
            },
            child: Container(
              width: double.infinity,
              height: 50.h,
              padding: EdgeInsets.only(left: 16.w, right: 13.w),
              child: Row(
                children: [
                  picked.isEmpty ? pickedEmpty() : pickedNotEmpty(),
                  const Spacer(),
                  const Icon(
                    Icons.arrow_drop_up,
                    color: style.bdbdbd,
                  ),
                ],
              ),
            ),
          ),
          const Divider(
            height: 0,
            thickness: 1,
            color: style.e8e8e8,
            indent: 17,
            endIndent: 17,
          ),
          Column(
            children: [
              for (int i in ints) buildRows(i),
            ],
          ),
        ],
      ),
    );
  }

Here are results这是结果

在此处输入图片说明

This is what I want to accomplish这就是我想要完成的

在此处输入图片说明

So I just want to move down this expanded dropdown and how to update these booles in the overlay if I don't use overlay it's working as it should but I need to open that dropdown on the top of another content.所以我只想向下移动这个扩展的下拉列表,以及如果我不使用覆盖它应该如何工作,如何更新覆盖中的这些布尔值,但我需要在另一个内容的顶部打开该下拉列表。 Thanks for the help.谢谢您的帮助。

Regarding the UI, it is like an Expansions Tile Widget in flutter.在 UI 方面,它就像 Flutter 中的 Expansions Tile Widget。 You can implement that dropdown with expansions tile and pass list of items in children, for expand , collapse tile after select each item, you can create a global key and control that in UI.您可以使用扩展磁贴和传递子项中的项目列表来实现该下拉菜单,对于在选择每个项目后expandcollapse磁贴,您可以创建一个全局键并在 UI 中控制它。

final GlobalKey<AppExpansionTileState> expansionTile = new GlobalKey();

collapse → expansionTile.currentState.collapse();折叠 → expansionTile.currentState.collapse();

ExpansionTile(
  title: Text(
    "Možete obeležiti više aktivnosti",
    style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.w500),
  ),
  children: <Widget>[
    // put items here
  ],
),

Use smart_select it is fully customizable and you can achieve the design you want easily using this library.使用smart_select它是完全可定制的,您可以使用此库轻松实现您想要的设计。

图片

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM