首页 > 解决方案 > 我应该编写哪种布局结构来匹配我的应用程序设计

问题描述

对于我的新 Flutter 项目,我对布局进行了一些研究,但仍然有点模糊。这是我要创建的布局:

在此处输入图像描述

经过一些研究并观看了一些视频,这似乎是 MaterialApp 代码:

    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          centerTitle: true,
          backgroundColor: Color(0xFF0E2E40),
          title: Text('City Discovery'),
          actions: [
            Image.asset(
              'assets/images/logoicon.png',
              width: 35,
            )
          ],
        ),
        body: ListView(
          children: [
            introSection,
            Image.asset(
              'assets/images/barman.png',
              width: 600,
              height: 240,
              fit: BoxFit.cover,
            ),
            crimeSection,
            mysterySection,
            bottomSection,
          ],
        ),
      ),
    );
  }

但是现在定义不同部分的布局非常困难。据我所知,应该有:

  1. ListView 使我的页面可滚动,它应该是
  2. introSection:用于 XYZ 的容器,包含 2 个文本部分的 2 行。
  3. 图片
  4. crimeSection:XYZ 的容器,3 行,用于 2 个文本部分和按钮。第一个文本部分分为 2 列图标和文本
  5. 神秘部分:XYZ 的容器,有 2 行,用于 2 个文本部分。第一个文本部分分为 2 列图标和文本
  6. 底部部分:标签?虽然选项卡似乎只是 appbar 的一部分,所以不确定替代方案是什么

我能找到的最接近的例子,但是改变代码并没有让我到任何地方: https ://github.com/flutter/website/blob/master/examples/layout/lakes/step6/lib/main.dart

出于某种原因,容器只能有 1 个孩子,所以这可能意味着我需要在我的容器中有一行,然后有孩子,然后两个文本部分都有 2 个孩子?编写一些简单的 UI 非常困难。

如果有人可以帮助我编写 introSection 和 bottomSection 的代码,我可能会自己解决剩下的问题。

标签: flutterflutter-layout

解决方案


我建议为可重用的小部件创建组件文件夹,如按钮、徽标、文本等。如果您有一个未在其他组件中使用的小部件,您可以将其分隔在同一个文件中但使用下划线,以使此小部件私有(它将仅在此文件中可见)。所有这些都将使您的代码更具可读性。

关于底部标签。

如果你想把它用作底部标签,你可以把它放在bottomNavigationBarScaffold 小部件的参数中。如果你需要在里面使用ListView,有可能,但是你需要传递选项卡的确切高度,因为TabView试图尽可能地扩展,与ListView.

在此处输入图像描述

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: LayoutExample(),
    );
  }
}

class LayoutExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      bottomNavigationBar: _BottomNavigationBar(),
      body: ListView(
        children: <Widget>[
          _IntroSection(),
          Placeholder(fallbackHeight: 200),
          _CrimeSection(),
          _MysterySection()
        ],
      ),
    );
  }
}

class _IntroSection extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 150,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: <Widget>[
          Text('Intro text1'),
          Text('Intro text2')
        ],
      ),
    );
  }
}

class _CrimeSection extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        border: Border.all(
          color: Colors.blueAccent,
        ),
      ),
      height: 200,
      child: Text('CrimeSection'),
    );
  }
}

class _MysterySection extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        border: Border.all(
          color: Colors.blueAccent,
        ),
      ),
      height: 200,
      child: Text('MysterySection'),
    );
  }
}

class _BottomNavigationBar extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BottomAppBar(
      child: Row(
        mainAxisSize: MainAxisSize.max,
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: <Widget>[
          IconButton(
            icon: Icon(Icons.menu),
            onPressed: () {},
          ),
          IconButton(
            icon: Icon(Icons.search),
            onPressed: () {},
          )
        ],
      ),
    );
  }
}

推荐阅读