【问题标题】:Flutter - Unidentified cause for pixel overflowFlutter - 像素溢出的不明原因
【发布时间】:2019-02-03 13:44:22
【问题描述】:

我一直在尝试将一些代码从 this flutter project 移植到 into this boilerplate sample 并遇到一些我似乎无法修复的像素溢出问题。

这是在 VSCode 调试控制台中抛出的错误;

flutter: ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
flutter: The following assertion was thrown during performLayout():
flutter: 'package:flutter/src/rendering/object.dart': Failed assertion: line 1514 pos 12:
flutter: '!_debugDoingThisLayout': is not true.

这是我正在使用的刺激错误的代码;

home_page.dart

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:cryptick_nice_ui/data/crypto_data.dart';
import 'package:cryptick_nice_ui/modules/crypto_presenter.dart';
import 'background.dart';
import 'package:cryptick_nice_ui/dependency_injection.dart';

void main() async {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      theme: new ThemeData(
          primarySwatch: Colors.pink,
          primaryColor: defaultTargetPlatform == TargetPlatform.iOS
              ? Colors.grey[100]
              : null),
      debugShowCheckedModeBanner: false,
      home: new HomePage(),
    );
  }
}


class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => new _HomePageState();
}

class _HomePageState extends State<HomePage> implements CryptoListViewContract {
  CryptoListPresenter _presenter;
  List<Crypto> _currencies;
  bool _isLoading;
  final List<MaterialColor> _colors = [Colors.blue, Colors.indigo, Colors.red];





  _HomePageState() {
    _presenter = new CryptoListPresenter(this);
  }

  @override
  void initState() {
    super.initState();
    _isLoading = true;
    _presenter.loadCurrencies();
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text(".",
          style: new TextStyle(
            fontFamily: 'PlayfairDisplay',
            letterSpacing: 0.8,
            color: const Color(0xFF273A48),
          )
          ),
          backgroundColor: const Color(0xFF273A48),
          elevation: 0.0,
        ),
        body: _isLoading
            ? new Center(
          child: new CircularProgressIndicator(),
        )
            : _cryptoWidget()
      );
  }

    Widget _cryptoWidget() {
    final _width1 = MediaQuery.of(context).size.width;
    final _height1 = MediaQuery.of(context).size.height;
    return new Container(
      decoration: new BoxDecoration(
      color: const Color(0xFF273A48),
    ),
        child: new Column(
          children: <Widget>[
            new CustomPaint(
            size: new Size(_width1, _height1),
            painter: new Background(),
          ),
            new Flexible(
              child: new ListView.builder(
                itemCount: _currencies.length,
                itemBuilder: (BuildContext context, int index) {
                  final int i = index ~/ 2;
                  final Crypto currency = _currencies[i];
                  final MaterialColor color = _colors[i % _colors.length];
                  if (index.isOdd) {
                    return new Divider();
                  }
                  return _getListItemUi(context, currency, color);
                },
              ),
            )
          ],
        )
      );
  }



  Widget _getListItemUi(BuildContext context, Crypto currency, MaterialColor color) {
    final _width2 = MediaQuery.of(context).size.width;
    final _height2 = MediaQuery.of(context).size.height;
    _presenter.loadCurrencies();
    final headerList = new ListView.builder(
      itemBuilder: (context, index) {
        EdgeInsets padding = index == 0?const EdgeInsets.only(
            left: 20.0, right: 10.0, top: 4.0, bottom: 30.0):const EdgeInsets.only(
            left: 10.0, right: 10.0, top: 4.0, bottom: 30.0);

        return new Padding(
          padding: padding,
          child: new InkWell(
            onTap: () {
              print('Card selected');
            },
            child: new Container(
              decoration: new BoxDecoration(
                borderRadius: new BorderRadius.circular(10.0),
                color: Colors.lightGreen,
                boxShadow: [
                  new BoxShadow(
                      color: Colors.black.withAlpha(70),
                      offset: const Offset(3.0, 10.0),
                      blurRadius: 15.0)
                ],
                image: new DecorationImage(
                  image: new ExactAssetImage(
                      ''),
                  fit: BoxFit.fitHeight,
                ),
              ),
//                                    height: 200.0,
              width: 200.0,
              child: new Stack(
                children: <Widget>[
                  new Align(
                    alignment: Alignment.bottomCenter,
                    child: new Container(
                        decoration: new BoxDecoration(
                            color: const Color(0xFF273A48),
                            borderRadius: new BorderRadius.only(
                                bottomLeft: new Radius.circular(10.0),
                                bottomRight: new Radius.circular(10.0))),
                        height: 30.0,
                        child: new Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: <Widget>[
                            new Text(
                              'hi',
                              style: new TextStyle(color: Colors.white),
                            )
                          ],
                        )),
                  )
                ],
              ),
            ),
          ),
        );
      },
      scrollDirection: Axis.horizontal,
      itemCount: _currencies.length,
    );

    final body = new Scaffold(
      appBar: new AppBar(
        title: new Text('cryp'),
        elevation: 0.0,
        backgroundColor: Colors.transparent,
        actions: <Widget>[
          new IconButton(icon: new Icon(Icons.shopping_cart, color: Colors.white,), onPressed: (){})
        ],
      ),
      backgroundColor: Colors.transparent,
      body: new Container(
        child: new Stack(
          children: <Widget>[
            new Padding(
              padding: new EdgeInsets.only(top: 10.0),
              child: new Column(
                crossAxisAlignment: CrossAxisAlignment.center,
                mainAxisSize: MainAxisSize.max,
                mainAxisAlignment: MainAxisAlignment.start,
                children: <Widget>[
                  new Align(
                    alignment: Alignment.centerLeft,
                    child: new Padding(
                        padding: new EdgeInsets.only(left: 8.0),
                        child: new Text(
                          'Trending News',
                          style: new TextStyle(
                            color: Colors.white70,
                            fontSize: 15.0,
                            ),
                        )),
                  ),
                  new Container(
                      height: 300.0, width: _width2, child: headerList),
                  new Expanded(child:
                  ListView.builder(itemBuilder: (context, index) {
                    return new ListTile(
                      title: new Column(
                        children: <Widget>[
                          new Row(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: <Widget>[
                              new Container(
                                height: 72.0,
                                width: 72.0,
                                decoration: new BoxDecoration(
                                    color: Colors.lightGreen,
                                    boxShadow: [
                                      new BoxShadow(
                                          color:
                                          Colors.black.withAlpha(70),
                                          offset: const Offset(2.0, 2.0),
                                          blurRadius: 2.0)
                                    ],
                                    borderRadius: new BorderRadius.all(
                                        new Radius.circular(12.0)),
                                    image: new DecorationImage(
                                      image: new ExactAssetImage(
                                        "cryptoiconsBlack/"+currency.symbol.toLowerCase()+"@2x.png",
                                      ),
                                      fit: BoxFit.cover,
                                    )),
                              ),
                              new SizedBox(
                                width: 8.0,
                              ),
                              new Expanded(
                                  child: new Column(
                                    mainAxisAlignment:
                                    MainAxisAlignment.start,
                                    crossAxisAlignment:
                                    CrossAxisAlignment.start,
                                    children: <Widget>[
                                      new Text(
                                        'My item header',
                                        style: new TextStyle(
                                            fontSize: 14.0,
                                            color: Colors.black87,
                                            fontWeight: FontWeight.bold),
                                      ),
                                      new Text(
                                        'Item Subheader goes here\nLorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry',
                                        style: new TextStyle(
                                            fontSize: 12.0,
                                            color: Colors.black54,
                                            fontWeight: FontWeight.normal),
                                      )
                                    ],
                                  )),
                              new Icon(
                                Icons.shopping_cart,
                                color: const Color(0xFF273A48),
                              )
                            ],
                          ),
                          new Divider(),
                        ],
                      ),
                    );
                  }))
                ],
              ),
            ),
          ],
        ),
      ),
    );

    return new Container(
      decoration: new BoxDecoration(
        color: const Color(0xFF273A48),
      ),
      child: new Stack(
        children: <Widget>[
          new CustomPaint(
            size: new Size(_width2, _height2),
            painter: new Background(),
          ),
          body,
        ],
      ),
    );
  }



  Widget _getSubtitleText(String priceUSD, String percentageChange) {
    TextSpan priceTextWidget = new TextSpan(
        text: "\$$priceUSD\n", style: new TextStyle(color: Colors.black));
    String percentageChangeText = "1 hour: $percentageChange%";
    TextSpan percentageChangeTextWidget;

    if (double.parse(percentageChange) > 0) {
      percentageChangeTextWidget = new TextSpan(
          text: percentageChangeText,
          style: new TextStyle(color: Colors.green));
    } else {
      percentageChangeTextWidget = new TextSpan(
          text: percentageChangeText, style: new TextStyle(color: Colors.red));
    }

    return new RichText(
        text: new TextSpan(
            children: [priceTextWidget, percentageChangeTextWidget]));
  }



  @override
  void onLoadCryptoComplete(List<Crypto> items) {
    // TODO: implement onLoadCryptoComplete

    setState(() {
      _currencies = items;
      _isLoading = false;
    });
  }

  @override
  void onLoadCryptoError() {
    // TODO: implement onLoadCryptoError
    }
  }

这是我用来创建灰色/白色托盘的background.dart 文件。

import 'package:flutter/material.dart';

class Background extends CustomPainter{
  @override
  void paint(Canvas canvas, Size size) {
    // TODO: implement paint
    _drawPentagone(canvas,  size);
  }

  _drawPentagone(Canvas canvas, Size size){
    var path = new Path();
    path.addPolygon([
      new Offset(size.width, size.height/5),
      new Offset(size.width, size.height),
      new Offset(0.0, size.height),
      new Offset(0.0, size.height/2.5),

    ], true);
    path.close();
    canvas.drawPath(path, new Paint()..color = Colors.white);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    // TODO: implement shouldRepaint
    return false;
  }

}

这是我在模拟器中得到的,底部写着BOTTOM OVERFLOWED BY 100 PIXELS

【问题讨论】:

    标签: android ios macos dart flutter


    【解决方案1】:

    问题是你让你的背景小部件和屏幕一样大:

    final _width1 = MediaQuery.of(context).size.width;
    final _height1 = MediaQuery.of(context).size.height;
    
    // ...
    
    new CustomPaint(
      size: new Size(_width1, _height1),
      painter: new Background(),
    ),
    

    顶部的AppBar大概占用了100像素的空间,而_cryptoWidget()只使用了AppBar下方的空间-

    您不需要MediaQuery 来创建屏幕填充小部件,只需使用不带任何尺寸的Container

    你的背景小部件被包裹在Column 中,下面还有另一个Flexible,这也很奇怪。如果背景是屏幕填充,Flexible 将如何适合下面?

    你想创建一个可滚动的视图吗?还是要在内容后面绘制背景小部件?

    【讨论】:

    • 这看起来很棒。我只想在内容后面绘制背景小部件,并计划在顶部添加一个水平 listView,如我正在使用的样板所示,在原始问题中链接。谢谢!
    • 如果要在内容后面绘制背景,内容必须是CustomPaint的子元素。
    • 好的,我相信这一切都有效,但我会在早上尝试。 (23:23) 在我国供参考
    • 好的,这看起来很棒,感谢您的帮助。我想我会使用new CustomPaint( size: new Size(_width, _height), painter: new Background(), child: _cryptoWidget() ),
    • 我认为你不需要size
    【解决方案2】:

    使用此代码并在 Scaffold 中添加任何您想要的内容

            Widget build(BuildContext context) {
              final width = MediaQuery.of(context).size.width;
              final height = MediaQuery.of(context).size.height;
              return new Container(
                child: new Stack(
                  children: <Widget>[
                    new CustomPaint(
                      painter: new Background(),
                      size: new Size(width, height),
                    ),
                    new Scaffold(
                        appBar: new AppBar(
                          title: new Text("Custom Background"),
                          backgroundColor: Colors.transparent,
                        ),
                        backgroundColor: Colors.transparent,
                        body: new Center(
                          child: new Text("Hello how are You? :)"),
                        ))
                  ],
                ),
              );
            }
    

    【讨论】:

      猜你喜欢
      • 2018-09-03
      • 2019-03-12
      • 2020-12-11
      • 2020-11-28
      • 2019-06-06
      • 2012-08-31
      • 2021-09-27
      • 2020-06-18
      • 1970-01-01
      相关资源
      最近更新 更多