引发了另一个异常:找不到材料小部件

时间:2018-12-19 16:46:05

标签: dart flutter

因此,基本上有一个产品编辑页面,其行为不同,称为uppon。

如果是第一次创建产品,那么它将显示在选项卡视图控制器中。

如果要更新产品,则将其主体放入支架中。

这是一些屏幕截图 Create item screnshoot update item screnshoot

当我通过创建产品提交时,我没有遇到任何错误。

但是当我通过更新产品提交时,尽管逻辑可行,但出现红色短屏

像这样

enter image description here

error Another exception was thrown: No Material widget found.

这是屏幕的代码

`

import 'package:flutter/material.dart';
import 'package:academy_app/models/products.dart';
import 'package:scoped_model/scoped_model.dart';
import 'package:academy_app/scoped-model/Products.dart';

class ProductEdit extends StatefulWidget {
  ProductEdit();

  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return ProductEditState();
  }
}

class ProductEditState extends State<ProductEdit> {
  String title;
  String description;
  double price;
  Product product;

  final focusnode2 = FocusNode();
  final focusnode3 = FocusNode();
  Map<String, dynamic> formData = {
    "name": null,
    "desc": null,
    "price": null,
    "image": "asset/foood.jpg"
  };

  GlobalKey<FormState> formkey = GlobalKey<FormState>();

  Widget buildTitle(productItem) {
    return TextFormField(
      initialValue: productItem != null ? productItem.title : "",
      validator: (String value) {
        if (value.isEmpty || value.length < 3) {
          return 'title cannot be empty';
        }
      },
      textInputAction: TextInputAction.next,
      decoration: InputDecoration(labelText: "Title"),
      onFieldSubmitted: (String value) {
        FocusScope.of(context).requestFocus(focusnode2);
      },
      onSaved: (String valuee) {
        setState(() {
          formData["name"] = valuee;
        });
      },
    );
  }

  Widget buildDesc(productItem) {
    return TextFormField(
      initialValue: productItem != null ? productItem.description : "",
      validator: (String value) {
        if (value.isEmpty || value.length < 3) {
          return 'Cant have that short description';
        }
      },
      textInputAction: TextInputAction.next,
      onFieldSubmitted: (value) {
        FocusScope.of(context).requestFocus(focusnode3);
      },
      focusNode: focusnode2,
      maxLines: 3,
      decoration: InputDecoration(labelText: "Description"),
      onSaved: (String valuee) {
        setState(() {
          formData["desc"] = valuee;
        });
      },
    );
  }

  Widget buildPrice(productItem) {
    return TextFormField(
      initialValue: productItem != null ? productItem.price.toString() : "",
      textInputAction: TextInputAction.done,
      focusNode: focusnode3,
      decoration: InputDecoration(labelText: " How much"),
      keyboardType: TextInputType.number,
      onFieldSubmitted: (value) {
        focusnode3.unfocus();
      },
      validator: (value) {
        if (!RegExp(r'^(?:[1-9]\d*|0)?(?:\.\d+)?$').hasMatch(value)) {
          return ' Enter numbers only';
        }
      },
      onSaved: (String valuee) {
        setState(() {
          formData["price"] = double.parse(valuee);
        });
      },
    );
  }

  void submitForm(Function addProduct, Function updateProduct, int index) {
    if (!formkey.currentState.validate()) {
      return;
    }
    formkey.currentState.save();
    setState(() {
      if (index == null) {
        addProduct(Product(
            price: formData["price"],
            title: formData["name"],
            description: formData["desc"],
            image: "asset/foood.jpg"));
      } else {
        updateProduct(
          Product(
              price: formData["price"],
              title: formData["name"],
              description: formData["desc"],
              image: "asset/foood.jpg"),
        );
      }
      Navigator.pushReplacementNamed(context, '/');
    });
  }

  Widget buildSubmitButton() {
    return ScopedModelDescendant<ProductsModel>(
      builder: (BuildContext context, Widget, ProductsModel) {
        return RaisedButton(
            child: Text("Save"),
            onPressed: () => submitForm(ProductsModel.addProduct,
                ProductsModel.updateProduct, ProductsModel.selected_index));
      },
    );
  }

  Widget _buildPageContent(BuildContext context, Product product) {
    final double deviceWidth = MediaQuery.of(context).size.width;
    final double targetWidth = deviceWidth > 550.0 ? 500.0 : deviceWidth * 0.95;
    final double targetPadding = deviceWidth - targetWidth;
    return GestureDetector(
      onTap: () {
        FocusScope.of(context).requestFocus(FocusNode());
      },
      child: Container(
        margin: EdgeInsets.all(10.0),
        child: Form(
          key: formkey,
          child: ListView(
            padding: EdgeInsets.symmetric(horizontal: targetPadding / 2),
            children: <Widget>[
              buildTitle(product),
              buildDesc(product),
              buildPrice(product),
              SizedBox(
                height: 10.0,
              ),
              buildSubmitButton()

            ],
          ),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {


    return ScopedModelDescendant<ProductsModel>(
      builder: (context, Widget child, ProductsModel) {
        product = ProductsModel.getproduct();



        return ProductsModel.selected_index == null
            ? _buildPageContent(context, product)
            : Scaffold(
                appBar: AppBar(
                  title: Text("Update Item"),
                ),
                body:_buildPageContent(context, product) ,
              );
      },
    );
  }
}

`

为什么我会出现红色屏幕错误?我对传递上下文感到困惑。为什么文本文件无法通过脚手架访问材料父对象?

5 个答案:

答案 0 :(得分:1)

尝试将应用程序包装在materialApp中,或将TextField包装在材料Widget中。

答案 1 :(得分:0)

由于错误提示未找到任何材料小部件,因此您需要将 _buildPateContent 函数的Container包装到 Material 小部件中。这是您可以做的更改:

  Widget _buildPageContent(BuildContext context, Product product) {
    final double deviceWidth = MediaQuery.of(context).size.width;
    final double targetWidth = deviceWidth > 550.0 ? 500.0 : deviceWidth * 0.95;
    final double targetPadding = deviceWidth - targetWidth;
    return GestureDetector(
      onTap: () {
        FocusScope.of(context).requestFocus(FocusNode());
      },
      child: Material(
          child: Container(
        margin: EdgeInsets.all(10.0),
        child: Form(
          key: formkey,
          child: ListView(
            padding: EdgeInsets.symmetric(horizontal: targetPadding / 2),
            children: <Widget>[
              buildTitle(product),
              buildDesc(product),
              buildPrice(product),
              SizedBox(
                height: 10.0,
              ),
              buildSubmitButton()
            ],
          ),
        ),
      ),
    ));
  }

答案 2 :(得分:0)

就我而言,我忘了用Scaffold小部件包装小部件。要使其正常工作,需要包装许多小部件。所以改变这个

Widget build(BuildContext context) {
  return YourScreenContent();
}

对此

Widget build(BuildContext context) {
  return Scaffold(
    body: YourScreenContent(),
  );
}

答案 3 :(得分:0)

我有同样的问题。 当我有这样的代码时,我得到了错误。

Widget _getLCSBar(int index) {
    return Container(
            decoration: BoxDecoration(
              border: Border.all(color: Colors.black, width: 0.1),
            ),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                _getLikeButton(index),
                _getCommentButton(index),
                _getShareButton(index),
              ],
            ));
}  

我所做的是用材料包裹它

  Widget _getLCSBar(int index) {
    return Material(
        child: Container(
            decoration: BoxDecoration(
              border: Border.all(color: Colors.black, width: 0.1),
            ),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                _getLikeButton(index),
                _getCommentButton(index),
                _getShareButton(index),
              ],
            )));
  }

问题已解决!

答案 4 :(得分:0)

只需将手势检测器包裹在材质中

return Material(
      child: GestureDetector(
          ...
      ),
);
相关问题