如何在父小部件上显示 SizeTransition 小部件(而不是展开它)

发布于 2025-01-10 18:01:04 字数 5051 浏览 0 评论 0原文

我正在寻找在 Flutter 上为表单创建一个 DropDownMenu 。

此下拉菜单不会粘贴/折叠到值选择器。

因此,我实现了位于行下方的展开列表视图。

我希望我的 SizedTransition 小部件能够越过父小部件而不是移动显示。这可能吗?我该怎么做?

我有:

Column [
   InkWell,
   SizeTransition -> ListView
]

我希望我的 SizeTransition 应该显示在父小部件上(而不是展开它)。

这是我的小部件代码 app_drop_down_form.dart : 该小部件将列表项显示在扩展列表中,并在未选择任何内容时显示默认标题。

class AppDropDownForm extends StatefulWidget {
  const AppDropDownForm({
    required this.defaultTitle,
    required this.dropList,
    Key? key,
  }) : super(key: key);

  final String defaultTitle;

  final List<AppDropDownItem> dropList;

  @override
  _AppDropDownFormState createState() => _AppDropDownFormState();
}

class _AppDropDownFormState extends State<AppDropDownForm>
    with SingleTickerProviderStateMixin {

  bool enableList = false;
  int? _selectedIndex;
  late AnimationController _expandController;
  late Animation<double> _expandAnimation;

  @override
  void initState() {
    _expandController = AnimationController(
        vsync: this, duration: const Duration(milliseconds: 300));
    _expandAnimation =
        CurvedAnimation(parent: _expandController, curve: Curves.easeInCubic);
    super.initState();
  }

  @override
  void dispose() {
    _expandController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    Container selectedItemWidget = _buildHeaderForm();

    return Column(children: <Widget>[
      InkWell(
          onTap: _performExpand,
          child: Container(
              decoration: BoxDecoration(
                  border: Border.all(color: AppTheme.lightGrey, width: 1),
                  borderRadius: enableList
                      ? const BorderRadius.vertical(top: Radius.circular(10))
                      : const BorderRadius.all(Radius.circular(10)),
                  color: Colors.white),
              padding: const EdgeInsets.symmetric(horizontal: 10),
              child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Expanded(child: selectedItemWidget),
                    const Icon(Icons.expand_more,
                        size: 24.0, color: AppTheme.thirdColor)
                  ]))),
      SizeTransition(
          sizeFactor: _expandAnimation, child: _buildExpandableSelectableList())
    ]);
  }

  Container _buildHeaderForm() {
    if (_selectedIndex == null) {
      return Container(
          padding: const EdgeInsets.symmetric(vertical: 15),
          child:
              Text(widget.defaultTitle, style: AppTheme.dropDownHintTextStyle));
    } else {
      var selectItem = widget.dropList
          .where((element) => element.index == _selectedIndex)
          .first;
      return Container(
          padding: const EdgeInsets.symmetric(vertical: 10),
          child: Row(children: [
            SizedBox(
                height: 25,
                width: 25,
                child: SvgPicture.asset(selectItem.iconPath,
                    color: AppTheme.black)),
            const SizedBox(width: 20),
            Text(selectItem.name, style: AppTheme.dropDownSelectedTextStyle)
          ]));
    }
  }

  Widget _buildExpandableSelectableList() {
    return Container(
        decoration: BoxDecoration(
            border: Border.all(color: AppTheme.lightGrey, width: 1),
            borderRadius:
                const BorderRadius.vertical(bottom: Radius.circular(10)),
            color: AppTheme.thirdColor),
        padding: const EdgeInsets.symmetric(horizontal: 20.0),
        child: ListView.builder(
            shrinkWrap: true,
            scrollDirection: Axis.vertical,
            physics: const BouncingScrollPhysics(
                parent: AlwaysScrollableScrollPhysics()),
            itemCount: widget.dropList.length,
            itemBuilder: (context, position) {
              return _buildExpandableItem(position);
            }));
  }

  InkWell _buildExpandableItem(int position) {
    var item =
        widget.dropList.where((element) => element.index == position).first;

    return InkWell(
        onTap: () {
          _onChanged(position);
        },
        child: Container(
            padding: const EdgeInsets.symmetric(vertical: 10),
            child: Row(children: [
              SizedBox(
                  height: 25,
                  width: 25,
                  child:
                      SvgPicture.asset(item.iconPath, color: AppTheme.white)),
              const SizedBox(width: 20),
              Text(item.name, style: AppTheme.dropDownLightTextStyle)
            ])));
  }

  void _onChanged(int position) {
    setState(() {
      _selectedIndex = position;
      _performExpand();
    });
  }

  void _performExpand() {
    enableList = !enableList;
    if (enableList) {
      _expandController.forward();
    } else {
      _expandController.reverse();
    }
  }
}
````

I am looking to create a DropDownMenu on Flutter for a form.

This DropDown menu is not pasted/collapse to the value selector.

So I implemented an Expand List View that comes just below the Row.

I want my SizedTransition widget to go over the parent widget and not shift the display. Is this possible? How do I do this?

I have :

Column [
   InkWell,
   SizeTransition -> ListView
]

I would like my SizeTransition should display over parent widget (not expand it).

There is my widget code app_drop_down_form.dart :
This widget take a list to item to display in expanded list and a default title when nothing is selected.

class AppDropDownForm extends StatefulWidget {
  const AppDropDownForm({
    required this.defaultTitle,
    required this.dropList,
    Key? key,
  }) : super(key: key);

  final String defaultTitle;

  final List<AppDropDownItem> dropList;

  @override
  _AppDropDownFormState createState() => _AppDropDownFormState();
}

class _AppDropDownFormState extends State<AppDropDownForm>
    with SingleTickerProviderStateMixin {

  bool enableList = false;
  int? _selectedIndex;
  late AnimationController _expandController;
  late Animation<double> _expandAnimation;

  @override
  void initState() {
    _expandController = AnimationController(
        vsync: this, duration: const Duration(milliseconds: 300));
    _expandAnimation =
        CurvedAnimation(parent: _expandController, curve: Curves.easeInCubic);
    super.initState();
  }

  @override
  void dispose() {
    _expandController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    Container selectedItemWidget = _buildHeaderForm();

    return Column(children: <Widget>[
      InkWell(
          onTap: _performExpand,
          child: Container(
              decoration: BoxDecoration(
                  border: Border.all(color: AppTheme.lightGrey, width: 1),
                  borderRadius: enableList
                      ? const BorderRadius.vertical(top: Radius.circular(10))
                      : const BorderRadius.all(Radius.circular(10)),
                  color: Colors.white),
              padding: const EdgeInsets.symmetric(horizontal: 10),
              child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Expanded(child: selectedItemWidget),
                    const Icon(Icons.expand_more,
                        size: 24.0, color: AppTheme.thirdColor)
                  ]))),
      SizeTransition(
          sizeFactor: _expandAnimation, child: _buildExpandableSelectableList())
    ]);
  }

  Container _buildHeaderForm() {
    if (_selectedIndex == null) {
      return Container(
          padding: const EdgeInsets.symmetric(vertical: 15),
          child:
              Text(widget.defaultTitle, style: AppTheme.dropDownHintTextStyle));
    } else {
      var selectItem = widget.dropList
          .where((element) => element.index == _selectedIndex)
          .first;
      return Container(
          padding: const EdgeInsets.symmetric(vertical: 10),
          child: Row(children: [
            SizedBox(
                height: 25,
                width: 25,
                child: SvgPicture.asset(selectItem.iconPath,
                    color: AppTheme.black)),
            const SizedBox(width: 20),
            Text(selectItem.name, style: AppTheme.dropDownSelectedTextStyle)
          ]));
    }
  }

  Widget _buildExpandableSelectableList() {
    return Container(
        decoration: BoxDecoration(
            border: Border.all(color: AppTheme.lightGrey, width: 1),
            borderRadius:
                const BorderRadius.vertical(bottom: Radius.circular(10)),
            color: AppTheme.thirdColor),
        padding: const EdgeInsets.symmetric(horizontal: 20.0),
        child: ListView.builder(
            shrinkWrap: true,
            scrollDirection: Axis.vertical,
            physics: const BouncingScrollPhysics(
                parent: AlwaysScrollableScrollPhysics()),
            itemCount: widget.dropList.length,
            itemBuilder: (context, position) {
              return _buildExpandableItem(position);
            }));
  }

  InkWell _buildExpandableItem(int position) {
    var item =
        widget.dropList.where((element) => element.index == position).first;

    return InkWell(
        onTap: () {
          _onChanged(position);
        },
        child: Container(
            padding: const EdgeInsets.symmetric(vertical: 10),
            child: Row(children: [
              SizedBox(
                  height: 25,
                  width: 25,
                  child:
                      SvgPicture.asset(item.iconPath, color: AppTheme.white)),
              const SizedBox(width: 20),
              Text(item.name, style: AppTheme.dropDownLightTextStyle)
            ])));
  }

  void _onChanged(int position) {
    setState(() {
      _selectedIndex = position;
      _performExpand();
    });
  }

  void _performExpand() {
    enableList = !enableList;
    if (enableList) {
      _expandController.forward();
    } else {
      _expandController.reverse();
    }
  }
}
````

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文