Flutter 布局 3 列宽 3 行深,图标和文本在下方 - 图标 OnPressed(不是导航栏,而是全屏)

Posted

技术标签:

【中文标题】Flutter 布局 3 列宽 3 行深,图标和文本在下方 - 图标 OnPressed(不是导航栏,而是全屏)【英文标题】:Flutter Layout 3 Columns Wide 3 Rows Deep with Icon and Text Below - Icons OnPressed (Not Navbar but Full Screen) 【发布时间】:2022-01-23 22:04:58 【问题描述】:

Flutter 和自学新手。尝试了多种方法,但没有找到“最佳选择”。

见截图。我需要制作类似于这个模型的东西。

需要 3 或 4 宽的图标,向下多行,图标和文本在下方居中。图标需要 OnPressed 或其他可操作代码才能导航到另一个屏幕/视图。文本不一定是可点击的。

我希望得到一些关于从哪里开始的指导。一些链接或代码示例会很棒,但我真的很想知道我走在正确的轨道上,并提供了创建类似屏幕的最佳解决方案。

提前谢谢你。

import 'package:welakaone/drawer/drawer.dart';
import 'package:welakaone/drawer/end_drawer.dart';
import 'package:welakaone/logic/custom_colors.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
//import 'package:welakaone/navigation/route.dart' as route;

class DirectoryScreen extends StatefulWidget 
  @override
  _DirectoryScreenState createState() => _DirectoryScreenState();


class _DirectoryScreenState extends State<DirectoryScreen> 
  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        systemOverlayStyle: SystemUiOverlayStyle.dark,
        backgroundColor: CustomColors.welakaoneBlack,
        title: AppBarTitle(),
        leading: Builder(
          builder: (context) 
            return IconButton(
              onPressed: () 
                Scaffold.of(context).openDrawer();
              ,
              icon: Icon(Icons.menu),
            );
          ,
        ),
        actions: <Widget>[
          Builder(
            builder: (context) 
              return IconButton(
                onPressed: () 
                  Scaffold.of(context).openEndDrawer();
                ,
                icon: Icon(Icons.person),
              );
            ,
          ),
        ],
      ),
      drawer: new MyDrawer(),
      endDrawer: new MyEndDrawer(
        uid: '',
      ),
      body: SingleChildScrollView(
        child: Container(
          height: MediaQuery.of(context).size.height,
          width: MediaQuery.of(context).size.width,
          decoration: const BoxDecoration(
            gradient: LinearGradient(
              colors: [
                CustomColors.welakaoneBlack,
                CustomColors.welakaoneBlueDark,
              ],
              begin: FractionalOffset(0.0, 0.0),
              end: FractionalOffset(1.6, 1.0),
              stops: [0.3, 1.0],
              tileMode: TileMode.clamp,
            ),
          ),
          child: RaisedButton(
            color: Colors.transparent,
            padding: EdgeInsets.all(8.0),
            onPressed: () ,
            // child: Container(
            //   height: 100,
            //   width: 200,
            //   child: Column(
            //     mainAxisSize: MainAxisSize.max,
            //     children: <Widget>[
            //       Padding(
            //         padding: const EdgeInsets.all(4.0),
            //         child: Icon(
            //           Icons.camera,
            //           color: Colors.white,
            //         ),
            //       ),
            //       Padding(
            //         padding: const EdgeInsets.all(2.0),
            //         child: Text(
            //           "Capture from Camera",
            //           style: TextStyle(
            //             color: Colors.yellow,
            //             fontWeight: FontWeight.bold,
            //           ),
            //         ),
            //       ),
            //     ],
            //   ),
            // ),
          ),
        ),
      ),
    );
  

【问题讨论】:

【参考方案1】:

让我们把你的问题分解成两个小问题

    创建 3 列宽 3 行的SomeWidget 为上述布局创建一个可点击的小部件。

解决方案:

第一个问题:Flutter 有一个专用的小部件来布局网格状结构,称为 GridView。使用它在该页面上创建 3x3 网格。

第二个问题:使用Column 小部件在其下方显示图标和文本。然后,使用InkWell 或GestureDetector 包装该列,使整个内容可点击

【讨论】:

谢谢!获得我想要的结果可能有更短的路径,但代码对我有用!【参考方案2】:

在研究了 HasilT 提供的解决方案后,我想出了对我有用的代码。可能有一种“更短”的方式可以到达我想去的地方,但这段代码可以完成工作!谢谢HasilT...感谢你,我今天学到了一些东西。

接下来我会添加 InkWell 的代码。

import 'package:welakaone/appbar/app_bar_title.dart';
import 'package:welakaone/drawer/drawer.dart';
import 'package:welakaone/drawer/end_drawer.dart';
import 'package:welakaone/logic/custom_colors.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
//import 'package:welakaone/navigation/route.dart' as route;

class HomeScreen extends StatefulWidget 
  @override
  _HomeScreenState createState() => _HomeScreenState();


class _HomeScreenState extends State<HomeScreen> 
  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        systemOverlayStyle: SystemUiOverlayStyle.dark,
        backgroundColor: CustomColors.welakaoneBlack,
        title: AppBarTitle(),
        leading: Builder(
          builder: (context) 
            return IconButton(
              onPressed: () 
                Scaffold.of(context).openDrawer();
              ,
              icon: Icon(Icons.menu),
            );
          ,
        ),
        actions: <Widget>[
          Builder(
            builder: (context) 
              return IconButton(
                onPressed: () 
                  Scaffold.of(context).openEndDrawer();
                ,
                icon: Icon(Icons.person),
              );
            ,
          ),
        ],
      ),
      drawer: new MyDrawer(),
      endDrawer: new MyEndDrawer(
        uid: '',
      ),
      body: Container(
        height: MediaQuery.of(context).size.height,
        width: MediaQuery.of(context).size.width,
        decoration: const BoxDecoration(
          gradient: LinearGradient(
            colors: [
              CustomColors.welakaoneBlack,
              CustomColors.welakaoneBlueDark,
            ],
            begin: FractionalOffset(0.0, 0.0),
            end: FractionalOffset(1.6, 1.0),
            stops: [0.3, 1.0],
            tileMode: TileMode.clamp,
          ),
        ),
        child: GridView.count(
          scrollDirection: Axis.vertical,
          shrinkWrap: true,
          primary: false,
          padding: const EdgeInsets.all(20),
          crossAxisSpacing: 10,
          mainAxisSpacing: 10,
          crossAxisCount: 3,
          children: <Widget>[
            InkWell(
              child: Column(
                children: [
                  Container(
                    child: Icon(
                      Icons.home,
                      size: 80,
                      color: Colors.white,
                    ),
                  ),
                  Container(
                    child: Text(
                      'TEST 1',
                      style: TextStyle(
                        fontSize: 18,
                        fontWeight: FontWeight.bold,
                        color: Colors.white,
                      ),
                    ),
                  ),
                ],
              ),
            ),
            InkWell(
              child: Column(
                children: [
                  Container(
                    child: Icon(
                      Icons.lock,
                      size: 80,
                      color: Colors.white,
                    ),
                  ),
                  Container(
                    child: Text(
                      'TEST 2',
                      style: TextStyle(
                        fontSize: 18,
                        fontWeight: FontWeight.bold,
                        color: Colors.white,
                      ),
                    ),
                  ),
                ],
              ),
            ),
            InkWell(
              child: Column(
                children: [
                  Container(
                    child: Icon(
                      Icons.login,
                      size: 80,
                      color: Colors.white,
                    ),
                  ),
                  Container(
                    child: Text(
                      'TEST 3',
                      style: TextStyle(
                        fontSize: 18,
                        fontWeight: FontWeight.bold,
                        color: Colors.white,
                      ),
                    ),
                  ),
                ],
              ),
            ),
            InkWell(
              child: Column(
                children: [
                  Container(
                    child: Icon(
                      Icons.person,
                      size: 80,
                      color: Colors.white,
                    ),
                  ),
                  Container(
                    child: Text(
                      'TEST 4',
                      style: TextStyle(
                        fontSize: 18,
                        fontWeight: FontWeight.bold,
                        color: Colors.white,
                      ),
                    ),
                  ),
                ],
              ),
            ),
            InkWell(
              child: Column(
                children: [
                  Container(
                    child: Icon(
                      Icons.door_back_door,
                      size: 80,
                      color: Colors.white,
                    ),
                  ),
                  Container(
                    child: Text(
                      'TEST 5',
                      style: TextStyle(
                        fontSize: 18,
                        fontWeight: FontWeight.bold,
                        color: Colors.white,
                      ),
                    ),
                  ),
                ],
              ),
            ),
            InkWell(
              child: Column(
                children: [
                  Container(
                    child: Icon(
                      Icons.place,
                      size: 80,
                      color: Colors.white,
                    ),
                  ),
                  Container(
                    child: Text(
                      'TEST 6',
                      style: TextStyle(
                        fontSize: 18,
                        fontWeight: FontWeight.bold,
                        color: Colors.white,
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  

【讨论】:

以上是关于Flutter 布局 3 列宽 3 行深,图标和文本在下方 - 图标 OnPressed(不是导航栏,而是全屏)的主要内容,如果未能解决你的问题,请参考以下文章

ListView 基础列表组件水平 列表组件图标组件

在 CListCtrl 中控制宽度/布局(图标视图)

Day15-CSS3

解决echarts渲染出图标和文字模糊问题

Flutter学习-多子布局Widget

如何使图像适合 Flutter 中的列宽?