使用 Dropdown_button2 包不适用于 Flutter 中的卡片视图

Using Dropdown_button2 package does not work for a card view in Flutter

我想制作一个 SVG 图标,我必须在此卡片上显示一个下拉菜单。 我正在使用 Dropdown_button2 包。 https://pub.dev/packages/dropdown_button2

我能够让下拉按钮独立工作。

我是这样做的

import 'package:flutter/material.dart';
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter_svg/svg.dart';

class CustomButtonTest extends StatefulWidget {
  const CustomButtonTest({Key? key}) : super(key: key);

  @override
  State<CustomButtonTest> createState() => _CustomButtonTestState();
}

class _CustomButtonTestState extends State<CustomButtonTest> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          DropdownButtonHideUnderline(
            child: DropdownButton2(
              customButton: SvgPicture.asset(
                'assets/threedots.svg',
                height: 30,
                width: 30,
              ),
              customItemsIndexes: const [4],
              customItemsHeight: 8,
              items: [
                ...MenuItems.firstItems.map(
                  (item) => DropdownMenuItem<MenuItem>(
                    value: item,
                    child: MenuItems.buildItem(item),
                  ),
                ),
              ],
              onChanged: (value) {
                MenuItems.onChanged(context, value as MenuItem);
              },
              itemHeight: 40,
              itemPadding: const EdgeInsets.only(left: 16, right: 16),
              dropdownWidth: 160,
              dropdownPadding: const EdgeInsets.symmetric(vertical: 6),
              dropdownDecoration: BoxDecoration(
                borderRadius: BorderRadius.circular(4),
                color: Colors.black87,
              ),
              dropdownElevation: 8,
              offset: const Offset(0, 8),
            ),
          ),
        ],
      ),
    );
  }
}

class MenuItem {
  final String text;
  final IconData icon;

  const MenuItem({
    required this.text,
    required this.icon,
  });
}

class MenuItems {
  static const List<MenuItem> firstItems = [
    profilepic,
    coverpic,
    nametag,
    aboutme
  ];

  static const profilepic =
      MenuItem(text: 'Profile Picture', icon: Icons.person_pin_outlined);
  static const coverpic = MenuItem(text: 'Cover Image', icon: Icons.image);
  static const nametag = MenuItem(text: 'Nametag', icon: Icons.person_add);
  static const aboutme =
      MenuItem(text: 'About Me', icon: Icons.bookmark_added_rounded);

  static Widget buildItem(MenuItem item) {
    return Row(
      children: [
        Icon(item.icon, color: Colors.white, size: 20),
        const SizedBox(
          width: 10,
        ),
        Text(
          item.text,
          style: const TextStyle(
            fontSize: 14,
            color: Colors.white,
          ),
        ),
      ],
    );
  }

  static onChanged(BuildContext context, MenuItem item) {
    switch (item) {
      case MenuItems.profilepic:
        //Do something
        break;
      case MenuItems.nametag:
        //Do something
        break;
      case MenuItems.coverpic:
        //Do something
        break;
      case MenuItems.aboutme:
        //Do something
        break;
    }
  }
}

但是将此代码与我的明信片结合使用可以减少按钮的使用 这是我的方法。

import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';

class ProfilePageCard extends StatefulWidget {
  const ProfilePageCard({Key? key}) : super(key: key);

  @override
  State<ProfilePageCard> createState() => _ProfilePageCardState();
}

class _ProfilePageCardState extends State<ProfilePageCard> {
  final double coverHeight = 232;
  final double profileHeight = 225;
  final double profileWidth = 169;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        clipBehavior: Clip.none,
        alignment: Alignment.centerLeft,
        children: [
          buildCoverImage(),
          const Positioned(
            top: 198,
            left: 350,
            child: Icon(
              Icons.perm_contact_cal,
              color: Colors.white,
            ),
          ),
          Positioned(
            top: 185,
            left: 6,
            child: buildProfileImage(),
          ),
          Positioned(
            top: 185 + 214,
            left: 148,
            child: DropdownButtonHideUnderline(
              child: DropdownButton2(
                customButton: SvgPicture.asset(
                  'assets/threedots.svg',
                  height: 30,
                  width: 30,
                ),
                customItemsIndexes: const [4],
                customItemsHeight: 8,
                items: [
                  ...MenuItems.firstItems.map(
                    (item) => DropdownMenuItem<MenuItem>(
                      value: item,
                      child: MenuItems.buildItem(item),
                    ),
                  ),
                ],
                onChanged: (value) {
                  MenuItems.onChanged(context, value as MenuItem);
                },
                itemHeight: 40,
                itemPadding: const EdgeInsets.only(left: 16, right: 16),
                dropdownWidth: 160,
                dropdownPadding: const EdgeInsets.symmetric(vertical: 6),
                dropdownDecoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(4),
                  color: Colors.black87,
                ),
                dropdownElevation: 8,
                offset: const Offset(0, 8),
              ),
            ),
          ),
        ],
      ),
    );
  }

  Widget buildCoverImage() => Container(
        color: Colors.grey,
        child: Image.network(
          'https://images.unsplash.com/photo-1488646953014-85cb44e25828?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8MXx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=60',
          width: double.infinity,
          height: coverHeight,
          fit: BoxFit.cover,
        ),
      );

  Widget buildProfileImage() => Container(
        decoration: BoxDecoration(
          border: Border.all(
            width: 6,
            color: Colors.white,
          ),
        ),
        child: Image.network(
          'https://images.unsplash.com/photo-1553860214-87b92d6c1e22?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8OXx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=60',
          width: profileWidth,
          height: profileHeight,
          fit: BoxFit.cover,
        ),
      );

  Widget buildUsername() => SizedBox(
        width: 193,
        child: IntrinsicHeight(
          child: Row(
            mainAxisAlignment: MainAxisAlignment.start,
            children: const [
              Text(
                "XYZ Traveler",
                style: TextStyle(
                    color: Colors.black,
                    fontWeight: FontWeight.bold,
                    fontFamily: 'Inter'),
              ),
            ],
          ),
        ),
      );
}

class MenuItem {
  final String text;
  final IconData icon;

  const MenuItem({
    required this.text,
    required this.icon,
  });
}

class MenuItems {
  static const List<MenuItem> firstItems = [home, share, settings, logout];

  static const home =
      MenuItem(text: 'Profile Picture', icon: Icons.person_pin_outlined);
  static const share = MenuItem(text: 'Cover Image', icon: Icons.image);
  static const settings = MenuItem(text: 'Nametag', icon: Icons.person_add);
  static const logout = MenuItem(text: 'Log Out', icon: Icons.logout);

  static Widget buildItem(MenuItem item) {
    return Row(
      children: [
        Icon(item.icon, color: Colors.white, size: 20),
        const SizedBox(
          width: 10,
        ),
        Text(
          item.text,
          style: const TextStyle(
            fontSize: 14,
            color: Colors.white,
          ),
        ),
      ],
    );
  }

  static onChanged(BuildContext context, MenuItem item) {
    switch (item) {
      case MenuItems.home:
        //Do something
        break;
      case MenuItems.settings:
        //Do something
        break;
      case MenuItems.share:
        //Do something
        break;
      case MenuItems.logout:
        //Do something
        break;
    }
  }
}

谁能指出我做错了什么?

您应该将 Stack 包裹在 Container 中,然后设置容器尺寸,使按钮仍保持在边框内。

class _ProfilePageCardState extends State<ProfilePageCard> {
  final double coverHeight = 232;
  final double profileHeight = 225;
  final double profileWidth = 169;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        color: Colors.red,
        height: 450,
        child: Stack(
          clipBehavior: Clip.none,
          alignment: Alignment.centerLeft,
          children: [
            Align(
                alignment: Alignment.topCenter,
                child: buildCoverImage()),
            const Positioned(
              top: 198,
              left: 350,
              child: Icon(
                Icons.perm_contact_cal,
                color: Colors.white,
              ),
            ),
            Positioned(
              top: 185,
              left: 6,
              child: buildProfileImage(),
            ),
            Positioned(
              top: 185 + 190,
              left: 148,
              child: DropdownButtonHideUnderline(
                child: DropdownButton2(
                  customButton: const Icon(Icons.more_horiz_rounded, color: Colors.black, size: 60,),
                  customItemsIndexes: const [4],
                  customItemsHeight: 8,
                  items: [
                    ...MenuItems.firstItems.map(
                          (item) => DropdownMenuItem<MenuItem>(
                        value: item,
                        child: MenuItems.buildItem(item),
                      ),
                    ),
                  ],
                  onChanged: (value) {
                    MenuItems.onChanged(context, value as MenuItem);
                  },
                  itemHeight: 40,
                  itemPadding: const EdgeInsets.only(left: 16, right: 16),
                  dropdownWidth: 160,
                  dropdownPadding: const EdgeInsets.symmetric(vertical: 6),
                  dropdownDecoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(4),
                    color: Colors.black87,
                  ),
                  dropdownElevation: 8,
                  offset: const Offset(0, 8),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }