无法实现类似于使用Flutter提供的示例的侧边栏菜单设计?

问题描述 投票:0回答:1

问题:

我正在 Flutter 中进行侧边栏菜单设计,我正在尝试复制下面设计示例中显示的外观和感觉。然而,我目前的实现并不能完全达到预期的结果。

实际设计:

  1. SideBarMenuTileDesgin-1
  2. SideBarMenuTileDesign-2

实现的设计:

  1. SideBarMenuUi

这是我写的代码:

bool _isHovered = false;
int _selectedActivityLogIndex = 0;
int _selectedSidebarIndex = 0;

void _setHovered(bool isHovered) {
  setState(() {
    _isHovered = isHovered;
  });
}

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: Row(
      children: [
        MouseRegion(
          onEnter: (_) => _setHovered(true),
          onExit: (_) => _setHovered(false),
          child: AnimatedContainer(
            duration: const Duration(milliseconds: 300),
            width: _isHovered ? 200.0 : 60.0,
            color: AppColors.sideBarMenuColor,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                _buildSidebarItem(SideBarMenuIcons.applicantSideMenuIcon1, 'Overview', 0),
                _buildSidebarItem(SideBarMenuIcons.applicantSideMenuIcon7, 'DBS', 1),
                _buildSidebarItem(SideBarMenuIcons.applicantSideMenuIcon6, 'Basic Disclosure', 2),
                _buildSidebarItem(SideBarMenuIcons.applicantSideMenuIcon5, 'Reference Check', 3),
                _buildSidebarItem(SideBarMenuIcons.applicantSideMenuIcon4, 'Right to Work', 4),
                _buildSidebarItem(SideBarMenuIcons.applicantSideMenuIcon3, 'Qualification', 5),
                _buildSidebarItem(SideBarMenuIcons.applicantSideMenuIcon2, 'ID', 6),
              ],
            ),
          ),
        ),
        Expanded(
          flex: 6,
          child: SingleChildScrollView(
            padding: const EdgeInsets.all(20.0),
            child: _buildContent(_selectedSidebarIndex),
          ),
        ),
      ],
    ),
  );
}

Widget _buildSidebarItem(String assetPath, String title, int index) {
  final isSelected = index == _selectedSidebarIndex;

  return GestureDetector(
    onTap: () {
      setState(() {
        _selectedSidebarIndex = index;
      });
    },
    child: Container(
      decoration: BoxDecoration(
        borderRadius: BorderRadius.only(
          bottomRight: Radius.circular(isSelected ? 20.0 : 0.0),
          topRight: Radius.circular(isSelected ? 20.0 : 0.0),
        ),
        color: isSelected ? AppColors.kWhite : AppColors.sideBarMenuColor,
      ),
      padding: const EdgeInsets.symmetric(vertical: 8.0),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          const SizedBox(width: 20.0),
          SvgPicture.asset(
            assetPath,
            width: 20.0,
            height: 20.0,
            color: AppColors.kSideMenuIconColor,
          ),
          if (_isHovered) ...[
            const SizedBox(width: 16.0),
            Expanded(
              child: Text(
                title,
                overflow: TextOverflow.ellipsis,
                style: TextStyle(
                  color: isSelected ? AppColors.kBlueColor : Colors.white,
                ),
                textAlign: TextAlign.left,
              ),
            ),
          ],
        ],
      ),
    ),
  );
}

问题: 我已经实现了侧边栏菜单,但设计与提供的示例不匹配。实现的设计与提供的参考设计并不完全一致。我如何修改我的代码或方法来实现示例中所示的设计?

任何帮助或建议将不胜感激!


flutter user-interface responsive-design riverpod windows-desktop-gadgets
1个回答
0
投票

想法是更改所选项目边框的 previousnext 索引,并将所选颜色更改为白色。我将每个标题包装在一个容器内以赋予其曲线,然后将其包装在另一个容器内以使该曲线可见(因为内部容器颜色是与抽屉颜色匹配的蓝色,我们需要外部容器使曲线可见)。您可以将

ListTitle
替换为任何小部件,我用它来快速制作原型。

import 'package:flutter/material.dart';

class IconButtonRow {
  final String title;

  IconButtonRow({required this.title});
}

final buttons = [
  IconButtonRow(title: "the"),
  IconButtonRow(title: "quick"),
  IconButtonRow(title: "brown"),
  IconButtonRow(title: "fox"),
  IconButtonRow(title: "jumped"),
  IconButtonRow(title: "over"),
  IconButtonRow(title: "the"),
  IconButtonRow(title: "lazy"),
  IconButtonRow(title: "dog"),
];

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

BorderRadius getBorderRadius(int? selected, int currentButton) {
  if (selected == null) {
    return BorderRadius.zero;
  }
  if (selected == currentButton - 1) {
    return const BorderRadius.only(
      topRight: Radius.circular(30),
    );
  }
  if (selected == currentButton + 1) {
    return const BorderRadius.only(
      bottomRight: Radius.circular(30),
    );
  }
  return BorderRadius.zero;
}

class _HomePageState extends State<HomePage> {
  int? selected;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      drawer: Drawer(
        backgroundColor: Colors.blue,
        child: Column(
          children: [
            for (var i = 0; i < buttons.length; i++)
              Container(
                color: Colors.white,
                child: Container(
                  decoration: BoxDecoration(
                    color: selected == i ? Colors.white : Colors.blue,
                    borderRadius: getBorderRadius(selected, i),
                  ),
                  child: ListTile(
                    title: Text(
                      buttons[i].title,
                      style: TextStyle(
                        color: selected == i ? Colors.blue : Colors.white,
                      ),
                    ),
                    onTap: () {
                      setState(() {
                        selected = i;
                      });
                    },
                  ),
                ),
              ),
          ],
        ),
      ),
      body: const Column(),
    );
  }
}

结果:单击标题即可查看更改。

Result

© www.soinside.com 2019 - 2024. All rights reserved.