【问题标题】:How do i correctly position these items horizontally in flutter to avoid overflow?我如何正确地水平放置这些项目以避免溢出?
【发布时间】:2023-02-01 13:13:35
【问题描述】:

我有一个负责标签栏设计的项目列表,我想让所有大小的框同时显示而不是水平溢出。

我将提供我的代码以便更好地说明。

经过一个多小时的争吵,这是我能想到的:

这就是我所期待的

我将给出下面视图的代码 sn-ps。

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:google_fonts/google_fonts.dart';

class JobsHeaderWidget extends StatefulWidget {
  const JobsHeaderWidget({
    Key key,
  }) : super(key: key);

  @override
  State<JobsHeaderWidget> createState() => _JobsHeaderWidgetState();
}

class _JobsHeaderWidgetState extends State<JobsHeaderWidget> {
  List<String> items = [
    "All",
    "Critical",
    "Open",
    "Closed",
    "Overdue",
  ];

  int current = 0;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(left: 10.0),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            'Jobs',
            style: GoogleFonts.poppins(
                color: Colors.black, fontSize: 18, fontWeight: FontWeight.w600),
          ),
          Row(
            children: [
              Text(
                'View Insights  ',
                style: GoogleFonts.poppins(
                    color: Color(0xff3498DB),
                    fontSize: 12,
                    fontWeight: FontWeight.w500),
              ),
              Icon(
                Icons.arrow_forward_ios,
                color: Color(0xff3498DB),
                size: 12,
              ),
            ],
          ),
          filterJobs()
        ],
      ),
    );
  }

  Widget filterJobs() {
    return Container(
      width: double.infinity,
      child: Column(
        children: [
          /// CUSTOM TABBAR
          SizedBox(
            width: double.infinity,
            height: 60,
            child: ListView.builder(
                physics: const BouncingScrollPhysics(),
                itemCount: items.length,
                scrollDirection: Axis.horizontal,
                itemBuilder: (ctx, index) {
                  return Column(
                    children: [
                      GestureDetector(
                        onTap: () {
                          setState(() {
                            current = index;
                          });
                        },
                        child: AnimatedContainer(
                          duration: const Duration(milliseconds: 300),
                          margin: const EdgeInsets.all(5),
                          decoration: BoxDecoration(
                            color: current == index
                                ? Color(0xff34495E)
                                : Color(0xffF5F5F5),
                            borderRadius: BorderRadius.circular(11),
                          ),
                          child: Center(
                            child: Padding(
                              padding: const EdgeInsets.only(
                                  left: 10.0, right: 10.0, top: 5, bottom: 5),
                              child: Text(
                                items[index],
                                style: GoogleFonts.poppins(
                                    fontSize: 10,
                                    fontWeight: FontWeight.w500,
                                    color: current == index
                                        ? Colors.white
                                        : Colors.grey),
                              ),
                            ),
                          ),
                        ),
                      ),
                    ],
                  );
                }),
          ),

          // Builder(
          //   builder: (context) {
          //     switch (current) {
          //       case 0:
          //         return AllNotificationItemsView();
          //       case 1:
          //         return JobsNotificationItemsView();
          //       case 2:
          //         return MessagesNotificationItemsView();
          //       case 3:
          //         return CustomersNotificationItemsView();
          //       default:
          //         return SizedBox.shrink();
          //     }
          //   },
          // )
        ],
      ),
    );
  }
}

【问题讨论】:

  • 顺便说一句,不推荐在函数中返回小部件。 filterJobs()应该是它自己的小部件
  • @UnicornsOnLSD 感谢提醒,我尝试提取它但它一直说“无法提取对封闭类方法的引用”
  • 你可以使用扩展的小部件
  • @tesseract 如果 vscode 中的自动功能不起作用,那么您可能必须手动将其删除

标签: flutter dart containers uitabbar


【解决方案1】:

溢出的原因是列表视图生成器。删除它并添加一个 Row 小部件。迭代其中的列表项,您将获得所需的输出。

完整代码:-

import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Image',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      debugShowCheckedModeBanner: false,
      home: const JobsHeaderWidget(),
    );
  }
}

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

  @override
  State<JobsHeaderWidget> createState() => _JobsHeaderWidgetState();
}

class _JobsHeaderWidgetState extends State<JobsHeaderWidget> {
  List<String> items = [
    "All",
    "Critical",
    "Open",
    "Closed",
    "Overdue",
  ];

  int current = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey,
      body: Padding(
        padding: const EdgeInsets.only(left: 10.0, right: 10, top: 5),
        child: Align(
          alignment: Alignment.topCenter,
          child: Container(
            constraints: const BoxConstraints(maxWidth: 610, maxHeight: 100),
            alignment: Alignment.center,
            width: double.infinity,
            child: IntrinsicWidth(
              child: FittedBox(
                fit: BoxFit.fitWidth,
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: [
                    for (int i = 0; i < items.length; i++) ...[
                      GestureDetector(
                        onTap: () {
                          setState(() {
                            current = i;
                          });
                        },
                        child: AnimatedContainer(
                          height: 40,
                          duration: const Duration(milliseconds: 300),
                          margin: const EdgeInsets.all(5),
                          padding: const EdgeInsets.only(
                              left: 15.0, right: 15.0, top: 5, bottom: 5),
                          decoration: BoxDecoration(
                            color: current == i
                                ? const Color(0xff34495E)
                                : const Color(0xffF5F5F5),
                            borderRadius: BorderRadius.circular(11),
                          ),
                          child: Center(
                            child: Text(
                              items[i],
                              style: GoogleFonts.poppins(
                                  fontSize: 19,
                                  fontWeight: FontWeight.w500,
                                  color: current == i
                                      ? Colors.white
                                      : Colors.grey),
                            ),
                          ),
                        ),
                      ),
                    ]
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

输出 : -

【讨论】:

  • 尝试调整屏幕大小,它会溢出。你的设计没有响应
  • 是的,我是,尝试将您的代码复制到 dartpad.dev,并尝试调整屏幕大小 i.stack.imgur.com/kj1kL.png 看看这个
  • 是的,它可以工作,但是当您的设备更大时,这意味着您的应用栏对于用户来说太大了。尝试在 chrome 上运行并尝试使屏幕尺寸更大,您的文本和按钮将变得如此之大并且对于用户来说不是一个好的设计
  • 当设计变大时,按钮将具有最大尺寸,因此当显示变大时,设计将停留在开始i.stack.imgur.com/GG5Q5.png
  • 谢谢@Ramji 看起来我会使用这个快速修复程序。
【解决方案2】:

嘿,要使应用栏不溢出,您必须使用扩展小部件。尝试包装您的 gestureDetector 或您创建的任何小部件,以便像这样为每个列表视图子项进行设计

 Expanded(
                child: GestureDetector(
                  onTap: () {
                    setState(() {
                      current = i;
                    });
                  },
                  child: AnimatedContainer(
                    height: 40,
                    duration: const Duration(milliseconds: 300),
                    margin: const EdgeInsets.all(5),
                    padding: const EdgeInsets.only(
                        left: 15.0, right: 15.0, top: 5, bottom: 5),
                    decoration: BoxDecoration(
                      color: current == i
                          ? const Color(0xff34495E)
                          : const Color(0xffF5F5F5),
                      borderRadius: BorderRadius.circular(11),
                    ),
                    child: Center(
                      child: Text(
                        items[i],
                        style: GoogleFonts.poppins(
                            fontSize: 12,
                            fontWeight: FontWeight.w500,
                            color: current == i ? Colors.white : Colors.grey),
                      ),
                    ),
                  ),
                ),
              ),

正如您在执行此操作时看到的那样,设计将如下所示

由于溢出问题,设计中的文本会消失,您可以将 text 小部件更改为此小部件 https://pub.dev/packages/auto_size_text

这是狙击手

@override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: Colors.grey,
        body: SafeArea(
          child: Padding(
            padding: const EdgeInsets.only(left: 5.0, right: 5, top: 20),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                for (int i = 0; i < items.length; i++) ...[
                  Expanded(
                    child: GestureDetector(
                      onTap: () {
                        setState(() {
                          current = i;
                        });
                      },
                      child: AnimatedContainer(
                        height: 40,
                        duration: const Duration(milliseconds: 300),
                        margin: const EdgeInsets.all(5),
                        padding: const EdgeInsets.only(
                            left: 5.0, right: 5.0, top: 5, bottom: 5),
                        decoration: BoxDecoration(
                          color: current == i
                              ? const Color(0xff34495E)
                              : const Color(0xffF5F5F5),
                          borderRadius: BorderRadius.circular(11),
                        ),
                        child: Center(
                          child: AutoSizeText(
                            items[i],
                            maxLines: 1,
                            style: GoogleFonts.poppins(
                                fontSize: 12,
                                fontWeight: FontWeight.w500,
                                color:
                                    current == i ? Colors.white : Colors.grey),
                          ),
                        ),
                      ),
                    ),
                  ),
                ]
              ],
            ),
          ),
        ));

但肯定文本会有些大有些小看起来像这样,这就是结果

【讨论】:

    【解决方案3】:

    我需要你的帮助来完成这个设计。我也想做同样的设计。所以,你可以告诉我你是如何通过点击按钮来调用这个函数的。那么,您可以与我分享代码吗?

    【讨论】:

      猜你喜欢
      • 2013-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-03
      • 1970-01-01
      • 1970-01-01
      • 2011-01-27
      • 2016-08-13
      相关资源
      最近更新 更多