Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”. Today I will share with you two tips for flutter development

Sticky title effect

Each section with a sticky title should be multiple pieces with SliverPinnedHeader and SliverList. Then setting pushPinnedChildren to true should provide the sticky title effect you’re looking for.

Flutter – How do I place the Gridview near the Card widget in the Column widget

Trying to create a user interface for my application. I need to design like this:But my latest user interface looks like this:In the second screenshot, I scroll down because my GridView widget (which has four card widgets) isn’t any closer to the other widgets. The other widgets are: title bar widgets, card widgets with graphics and subgraph widgets. I put the title bar and graphics card widgets on the stack to display them on top. I put these two combined widgets in a column with the GridView widget. I wrap this column of widgets with the SingleChildScrollView widget because I want the page to be scrollable.So my question is: How do I place the GridView widget closer to the card widget as I did in the first image?Here’s my code for this 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(a);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 ı Gor"),),); } 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(
                      The '%' + s1,
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 16,
                        fontWeight: FontWeight.w300,
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
        Column(
          / / Sonuclanan
          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(
                      The '%' + 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;
}
Copy the code

Additional question: Can you let me know if I can do something more efficient? Thank you very much!

The best answer

Maybe it happened because of this piece of code on the stack. This container takes up your full-screen size. This is why your GridView project is generated immediately after the screen size. Try to remove this container or reduce its height.

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

Update: You can try it I haven’t tried it but it might help

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