【问题标题】:How to put Gridview closer to Card widget in Column widget如何使 Gridview 更靠近 Column 小部件中的 Card 小部件
【发布时间】:2020-12-10 15:23:42
【问题描述】:

我正在尝试为我的应用创建用户界面。我需要这样设计:

但我最近的 UI 是这样的:

在第二个屏幕截图中,我向下滚动,因为我的 gridview 小部件(有 4 个卡片小部件)没有更接近其他小部件。其他小部件是:标题栏小部件,具有图形和子图小部件的卡片小部件。我将标题栏和图形卡小部件放在堆栈中,以便在上面显示它们。我将这两个组合的小部件与我的 gridview 小部件放在一个列中。我用 SingleChildScrollView 小部件包装这个列小部件,因为我希望我的页面是可滚动的。 所以我的问题是:如何将 gridview 小部件靠近我的卡片小部件,就像在第一张图片中一样?

这是我用于此 UI 的代码:

import 'package:flutter/material.dart';
import 'package:flutter_circular_chart/flutter_circular_chart.dart';
import 'package:intl/intl.dart';
import 'baskana_rapor_icon_icons.dart';

// ignore: must_be_immutable
class MainPage extends StatelessWidget {
  List<Widget> widgets = new List();
  List<CircularSegmentEntry> dataList = _loadData();
  int _totalCount;
  Widget s1, s2, total;
  final formatter = new NumberFormat("#,##");

  @override
  Widget build(BuildContext context) {
    widgets.add(_buildBody(context));

    return Scaffold(body: _buildBody(context));
  }

  Widget _buildBody(BuildContext context) {
    return LayoutBuilder(
      builder: (BuildContext context, BoxConstraints viewportConstraints) {
        return SingleChildScrollView(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            //mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Stack(
                children: <Widget>[
                  Container(
                    height: MediaQuery.of(context).size.height,
                    width: MediaQuery.of(context).size.width,
                  ),
                  _buildTitleBar(context),
                  Positioned(bottom: 65, left: 35, child: _buildCard(context)),
                ],
              ),
              _buildGridButtons(context),
            ],
          ),
        );
      },
    );
  }

  Widget _buildGridButtons(BuildContext context) {
    int itemWidth = 80;
    int itemHeight = 40;
    return SafeArea(
      child: Column(
        children: [
          GridView.count(
            crossAxisCount: 2,
            childAspectRatio: (itemWidth / itemHeight),
            shrinkWrap: true,
            primary: true,
            children: [
              GestureDetector(
                onTap: () {
                  Navigator.pushNamed(context, '/MahalleRapor');
                },
                child: Card(
                  color: Colors.white,
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.all(
                      Radius.circular(25),
                    ),
                  ),
                  child: Stack(
                    alignment: Alignment.center,
                    children: [
                      Column(
                        mainAxisSize: MainAxisSize.min,
                        crossAxisAlignment: CrossAxisAlignment.center,
                        mainAxisAlignment: MainAxisAlignment.spaceAround,
                        children: [
                          Icon(
                            BaskanaRaporIcon.mahalle_raporu,
                            color: Colors.redAccent,
                            size: 30,
                          ),
                          Text(
                            'Mahalle Raporu',
                            style: TextStyle(
                              color: Colors.black87,
                              fontSize: 20,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                          SizedBox(
                            height: 5,
                          )
                        ],
                      ),
                      Positioned(
                        bottom: 0,
                        right: 1,
                        left: 1,
                        child: Divider(
                          color: Colors.redAccent,
                          endIndent: 45,
                          indent: 50,
                          thickness: 3,
                        ),
                      ),
                    ],
                  ),
                ),
              ),
              GestureDetector(
                onTap: () {
                  Navigator.pushNamed(context, '/BirimRapor');
                },
                child: Card(
                  color: Colors.white,
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.all(
                      Radius.circular(25),
                    ),
                  ),
                  child: Stack(
                    alignment: Alignment.center,
                    children: [
                      Column(
                        mainAxisSize: MainAxisSize.min,
                        crossAxisAlignment: CrossAxisAlignment.center,
                        mainAxisAlignment: MainAxisAlignment.spaceAround,
                        children: [
                          Icon(
                            BaskanaRaporIcon.birim_raporu,
                            color: Colors.green[300],
                            size: 30,
                          ),
                          Text(
                            'Birim Raporu',
                            style: TextStyle(
                              color: Colors.black87,
                              fontSize: 20,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                          SizedBox(
                            height: 5,
                          )
                        ],
                      ),
                      Positioned(
                        bottom: 0,
                        right: 1,
                        left: 1,
                        child: Divider(
                          color: Colors.green[300],
                          endIndent: 45,
                          indent: 50,
                          thickness: 3,
                        ),
                      ),
                    ],
                  ),
                ),
              ),
              GestureDetector(
                onTap: () {
                  Navigator.pushNamed(context, '/GelirGider');
                },
                child: Card(
                  color: Colors.white,
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.all(
                      Radius.circular(25),
                    ),
                  ),
                  child: Stack(
                    alignment: Alignment.center,
                    children: [
                      Column(
                        mainAxisSize: MainAxisSize.min,
                        crossAxisAlignment: CrossAxisAlignment.center,
                        mainAxisAlignment: MainAxisAlignment.spaceAround,
                        children: [
                          Icon(
                            BaskanaRaporIcon.gelir_gider,
                            color: Colors.yellow[700],
                            size: 30,
                          ),
                          Text(
                            'Gelir / Gider',
                            style: TextStyle(
                              color: Colors.black87,
                              fontSize: 20,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                          SizedBox(
                            height: 5,
                          )
                        ],
                      ),
                      Positioned(
                        bottom: 0,
                        right: 1,
                        left: 1,
                        child: Divider(
                          color: Colors.yellow[700],
                          endIndent: 45,
                          indent: 50,
                          thickness: 3,
                        ),
                      ),
                    ],
                  ),
                ),
              ),
              GestureDetector(
                onTap: () {
                  Navigator.pushNamed(context, '/BaskanaMesaj');
                },
                child: Card(
                  color: Colors.white,
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.all(
                      Radius.circular(25),
                    ),
                  ),
                  child: Stack(
                    alignment: Alignment.center,
                    children: [
                      Column(
                        mainAxisSize: MainAxisSize.min,
                        crossAxisAlignment: CrossAxisAlignment.center,
                        mainAxisAlignment: MainAxisAlignment.spaceAround,
                        children: [
                          Icon(
                            BaskanaRaporIcon.baskana_msg,
                            color: Colors.blueAccent,
                            size: 30,
                          ),
                          Text(
                            'Başkana Mesaj',
                            style: TextStyle(
                              color: Colors.black87,
                              fontSize: 20,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                          SizedBox(
                            height: 5,
                          )
                        ],
                      ),
                      Positioned(
                        bottom: 0,
                        right: 1,
                        left: 1,
                        child: Divider(
                          color: Colors.blueAccent,
                          endIndent: 45,
                          indent: 50,
                          thickness: 3,
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ],
          )
        ],
      ),
    );
  }

  // ignore: todo
  //TODO: Better implementation of UI
  final double buttonHeight = 50;

  Widget _buildCard(BuildContext context) {
    return Center(
      child: Container(
        height: 500 + buttonHeight,
        child: Stack(
          alignment: Alignment.center,
          overflow: Overflow.visible,
          children: [
            Card(
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(15),
                side: BorderSide(color: Colors.blueGrey, width: 0.5),
              ),
              child: Container(
                height: MediaQuery.of(context).size.height * .65,
                width: MediaQuery.of(context).size.width * .80,
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  mainAxisSize: MainAxisSize.max,
                  children: <Widget>[
                    Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Text(
                        "Genel Durum",
                        style: TextStyle(
                          fontSize: 20,
                          color: Colors.black,
                          letterSpacing: 0.3,
                        ),
                      ),
                    ),
                    Divider(
                      color: Colors.grey,
                      thickness: 0.3,
                      endIndent: 10,
                      indent: 10,
                    ),
                    _buildChart(dataList),
                    SizedBox(
                      height: 20,
                    ),
                    _buildSubGraph(),
                    SizedBox(
                      height: 40,
                    ),
                  ],
                ),
              ),
            ),
            Positioned(
              //top: -buttonHeight /2,
              bottom: 27,
              child: _buildDetailsButton(context),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildDetailsButton(BuildContext context) {
    return ButtonTheme(
      height: 50,
      minWidth: 100,
      child: RaisedButton(
        onPressed: () {
          Navigator.pushNamed(context, '/DetailPage');
        },
        color: Colors.white,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(30),
        ),
        child: Text("Detayları Gör"),
      ),
    );
  }

  Row _buildSubGraph() {
    String s1 = formatter.format((dataList[1].value / _totalCount) * 100);
    String s0 = formatter.format((dataList[0].value / _totalCount) * 100);

    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceAround,
      children: [
        Column(
          //İşlemde
          children: [
            Text(
              dataList[1].rankKey,
              style: TextStyle(
                fontSize: 18,
                color: Colors.black87,
              ),
            ),
            Container(
              decoration: BoxDecoration(
                color: dataList[1].color,
                borderRadius: BorderRadius.only(
                  topRight: Radius.circular(5),
                  bottomRight: Radius.circular(5),
                  bottomLeft: Radius.circular(5),
                ),
              ),
              height: 50,
              width: 150,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Text(
                    '${dataList[1].value.toInt()}',
                    style: TextStyle(
                      color: Colors.white,
                      fontSize: 20,
                    ),
                  ),
                  SizedBox(
                    width: 50,
                  ),
                  Flexible(
                    child: Text(
                      '%' + s1,
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 16,
                        fontWeight: FontWeight.w300,
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
        Column(
          //Sonuçlanan
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            Text(
              dataList[0].rankKey,
              style: TextStyle(
                fontSize: 18,
                color: Colors.black87,
              ),
            ),
            Container(
              height: 50,
              width: 150,
              decoration: BoxDecoration(
                color: dataList[0].color,
                borderRadius: BorderRadius.only(
                  topRight: Radius.circular(5),
                  bottomRight: Radius.circular(5),
                  bottomLeft: Radius.circular(5),
                ),
              ),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Text(
                    '${dataList[0].value.toInt()}',
                    style: TextStyle(
                      color: Colors.white,
                      fontSize: 20,
                    ),
                  ),
                  SizedBox(
                    width: 50,
                  ),
                  Flexible(
                    child: Text(
                      '%' + s0,
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 16,
                        fontWeight: FontWeight.w300,
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ],
        )
      ],
    );
  }

  //Map<String, double> dataMap, List<Color> colorList,BuildContext context
  Widget _buildChart(List<CircularSegmentEntry> dataList) {
    _totalCount = _findTotalCount(dataList);
    s1 = _createText("TOPLAMDA", 20, Colors.grey[600], false);
    s1 = _createText("TALEP", 20, Colors.grey[600], false);
    total = _createText('$_totalCount', 24, Colors.black87, true);
    return Container(
      child: AnimatedCircularChart(
        size: Size(500, 250),
        initialChartData: <CircularStackEntry>[
          CircularStackEntry(
            <CircularSegmentEntry>[
              dataList[0],
              dataList[1],
            ],
          ),
        ],
        chartType: CircularChartType.Radial,
        startAngle: -90,
        holeRadius: 25,
        holeLabel:
            "TOPLAMDA \n\t\t\t\t\t\t\t $_totalCount \n\t\t\t TALEP", // $s1 \n\t\t\t\t\t\t\t $total \n\t\t\t $s2
      ),
    );
  }

  Widget _buildTitleBar(BuildContext context) {
    return Align(
      alignment: Alignment.topCenter,
      child: Column(
        children: <Widget>[
          Container(
            height: MediaQuery.of(context).size.height * .247,
            decoration: BoxDecoration(
              color: Colors.blue,
              shape: BoxShape.rectangle,
              borderRadius: BorderRadius.vertical(
                bottom: Radius.circular(25),
              ),
            ),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Icon(
                  Icons.assessment,
                  color: Colors.white,
                ),
                Text(
                  "Genel Durum",
                  style: TextStyle(
                    color: Colors.white,
                    fontSize: 28,
                    fontWeight: FontWeight.bold,
                    letterSpacing: 0.5,
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

Widget _createText(String msg, double size, Color color, bool isBold) {
  return Text(
    msg,
    style: TextStyle(
      color: color,
      fontSize: size,
      fontWeight: isBold ? FontWeight.bold : FontWeight.normal,
    ),
  );
}

int _findTotalCount(List<CircularSegmentEntry> dataList) {
  int result = 0;
  for (int i = 0; i < dataList.length; i++) {
    result += (dataList[i].value).toInt();
  }
  return result;
}

List<CircularSegmentEntry> _loadData() {
  List<CircularSegmentEntry> dataList = [];
  CircularSegmentEntry chartData1 =
      new CircularSegmentEntry(150, Colors.greenAccent, rankKey: 'Sonuçlanan');
  CircularSegmentEntry chartData2 =
      new CircularSegmentEntry(150, Colors.blue, rankKey: 'İşlemde');
  dataList.add(chartData1);
  dataList.add(chartData2);
  return dataList;
}

额外的问题:如果有什么我可以做的更有效的设计,你能告诉我吗?谢谢!

【问题讨论】:

    标签: flutter user-interface dart flutter-dependencies


    【解决方案1】:

    这可能是因为您的堆栈中的这段代码。此容器采用您的全屏尺寸。这就是为什么您的 GridView 项目在屏幕大小之后立即构建的原因。尝试移除此 Container 或降低其高度。

    Container(
         height: MediaQuery.of(context).size.height,
         width: MediaQuery.of(context).size.width,
       ),
    

    更新: 你可以试试这个。我还没有尝试过,但也许这会有所帮助

    Stack(
        children: <Widget>[
          Align(
            alignment: Alignment.topCenter,
            child: _buildTitleBar(context),
          ),
          Align(
            alignment: Alignment.topCenter,
            child: Container(
              margin: EdgeInsets.only(top: 100),
              child: _buildCard(context),
            ),
          )
        ],
      )
    

    【讨论】:

    • 当我尝试这个时,我的标题栏和我的卡片小部件卡在了屏幕顶部,所以如果我摆脱了那个容器,我应该改变堆栈中的其他东西。我会等待你的想法,同时我将尝试为堆栈定位小部件
    • 您可以使用 Container 代替 Position。并在顶部留出一些余量。并且还使用 Align 包裹该容器并使对齐 topCenter。我没有测试这个以及你的代码。但这里的主要问题是您的容器具有整个屏幕的高度。
    • 如果我用一个容器包装我的 gridview 小部件和卡片小部件以便垂直排列它们会怎样。如果是这样,我该如何重新构建我的屏幕,因为我的卡片不会进一步显示标题栏小部件。
    • @TahaAteş 我添加了一段代码。请尝试一下。也许这会有所帮助。
    • 我使用了你的解决方案,它有效,但又出现了一点问题,我怎样才能让 gridview 小部件更靠近我的卡片小部件?我想不通,因为这两个小部件在一个列小部件中,我想把它们画得更近一点。即使我有确切的数字 15px。
    猜你喜欢
    • 1970-01-01
    • 2021-03-08
    • 2019-12-21
    • 2019-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-05
    相关资源
    最近更新 更多