0

我的页面上有一个容器,它应该有图像或文本,具体取决于自定义对话框小部件中给出的那个。我在一个单独的无状态类中创建了这个小部件。我从创建容器的页面调用它。

自定义对话框


class CustomDialog extends StatelessWidget {
  TextEditingController textController;

  BuildContext context;
  Function saveAction;
  CustomDialog({
    this.context,
    this.textController,
    this.saveAction,
  });

  _getText(String text) {
    return Text(
      text,
      textAlign: TextAlign.center,
      style: TextStyle(color: Colors.black, fontSize: 16),
    );
  }

  _buildIconHolder(IconData icon) {
    return Container(
      width: 60,
      height: 60,
      decoration:
          BoxDecoration(shape: BoxShape.circle, color: Colors.yellowAccent),
      child: Icon(icon, size: 40, color: Colors.blue),
    );
  }

  _buildImagePickerElements() {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        _getText("Add Image"),
        SizedBox(height: 10),
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: <Widget>[
            _buildIconHolder(Icons.folder_open),
            _getText("or"),
            _buildIconHolder(Icons.camera_alt),
          ],
        ),
      ],
    );
  }

  _buildTextInput() {
    return Card(
      color: Colors.orange[600],
      shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.all(Radius.circular(20))),
      child: Padding(
        padding: EdgeInsets.all(10),
        child: TextField(
          controller: textController,
          decoration: InputDecoration(
              border: InputBorder.none, hintText: "hint text here"),
          keyboardType: TextInputType.emailAddress,
          textAlign: TextAlign.center,
          textInputAction: TextInputAction.next,
          maxLines: 4,
        ),
      ),
    );
  }

  _buildPrimaryButton(Function fn) {
    return InkWell(
      child: GestureDetector(
        child: Container(
          padding: EdgeInsets.only(top: 20.0, bottom: 20.0),
          decoration: BoxDecoration(
              color: Colors.purple,
              borderRadius: BorderRadius.all(Radius.circular(10))),
          child: Text("Save",
              textAlign: TextAlign.center,
              style: TextStyle(color: Colors.white)),
        ),
        onTap: () => {
          fn,
          Navigator.of(ctx).pop();
      ),
    );
  }

  _getDialogElements() {
    return Column(
      mainAxisAlignment: MainAxisAlignment.start,
      crossAxisAlignment: CrossAxisAlignment.stretch,
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        _buildImagePickerElements(),
        SizedBox(height: 10),
        Row(
          children: <Widget>[
            Expanded(
              child: Padding(
                padding: EdgeInsets.only(right: 10),
                child: Divider(color: Colors.purple, thickness: 2),
              ),
            ),
            _getText("or"),
            Expanded(
              child: Padding(
                padding: EdgeInsets.only(left: 10),
                child: Divider(color: Colors.purple, thickness: 2),
              ),
            ),
          ],
        ),
        SizedBox(height: 10),
        _getText("Describe Below"),
        SizedBox(height: 10),
        _buildTextInput(),
        SizedBox(height: 10),
        _buildPrimaryButton(saveAction),
      ],
    );
  }

  Widget build(BuildContext context) {
    return AlertDialog(
      backgroundColor: Colors.blueGrey,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.all(Radius.circular(20)),
      ),
      content: SingleChildScrollView(
        child: Container(width: 400.0, child: _getDialogElements()),
      ),
    );
  }
}

主页

import 'package:custom_dialog/custom_dialog.dart';
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  TextEditingController _controller = new TextEditingController();
  String _field = "";

  clicked(BuildContext ctx) {
    // setState(() {
    if (_controller.text.isNotEmpty && _controller.text != null) {
      _field = _controller.text;
    }
    //   Navigator.of(ctx).pop();
    // });
  }

  _makeContainerAText() {
    return Container(
      width: 40,
      height: 60,
      child: Text(_field),
    );
  }

  _makeContainerAActionBtn() {
    return Container(
      width: 40,
      height: 60,
      child: FloatingActionButton(
        backgroundColor: Colors.yellow,
        onPressed: () {
          setState(() {
            print("Action button pressed");
            showDialog(
              context: context,
              builder: (BuildContext context) => CustomDialog(
                context: context,
                textController: _controller,
                saveAction: clicked(context),
              ),
            );
          });
        },
        child: Icon(
          Icons.add,
          color: Colors.purple,
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Container Home Page"),
      ),
      body: Center(
        child: Stack(
          children: <Widget>[
            InkWell(
              splashColor: Colors.orange[400],
              highlightColor: Colors.purple,
              child: Material(
                elevation: 10,
                borderRadius: BorderRadius.all(Radius.circular(10)),
                child: DecoratedBox(
                  decoration: BoxDecoration(
                    shape: BoxShape.rectangle,
                    color: Colors.orange[600],
                    borderRadius: BorderRadius.all(Radius.circular(10)),
                  ),
                  child: Padding(
                    padding: EdgeInsets.all(25),
                    child: validate
                        ? _makeContainerAText()
                        : _makeContainerAActionBtn(),
                  ),
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

简而言之,我希望容器在添加文本或图像后看起来像下面链接中给出的容器。

Container_Image_Text_Example

我不能在自定义对话框类中使用 setState,因为它是无状态的。如果我让它有状态,那么当我单击执行显示对话框的容器时,我无法在屏幕上看到它。我尝试在clicked()方法中使用 setState 但最终出现以下错误。

════════ Exception caught by animation library ═════════════════════════════════
The following assertion was thrown while notifying status listeners for AnimationController:
setState() or markNeedsBuild() called during build.

This _ModalScope<dynamic> widget cannot be marked as needing to build because the framework is already in the process of building widgets.  A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase.
The widget on which setState() or markNeedsBuild() was called was: _ModalScope<dynamic>-[LabeledGlobalKey<_ModalScopeState<dynamic>>#f69dd]
    state: _ModalScopeState<dynamic>#32d94
The widget which was currently being built when the offending call was made was: Builder
    dirty
When the exception was thrown, this was the stack
#0      Element.markNeedsBuild.<anonymous closure> 
package:flutter/…/widgets/framework.dart:3896
#1      Element.markNeedsBuild 
package:flutter/…/widgets/framework.dart:3911
#2      State.setState 
package:flutter/…/widgets/framework.dart:1168
#3      _ModalScopeState._routeSetState 
package:flutter/…/widgets/routes.dart:664
#4      ModalRoute.setState 
package:flutter/…/widgets/routes.dart:784
...
The AnimationController notifying status listeners was: AnimationController#073ac(⏮ 0.000; paused; for _DialogRoute<dynamic>)
════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════
setState() or markNeedsBuild() called during build.
The relevant error-causing widget was
    MaterialApp 
lib/main.dart:9
════════════════════════════════════════════════════════════════════════════════

4

0 回答 0