Как передать виджет динамически в параметре конструктора класса - PullRequest
1 голос
/ 08 февраля 2020

Это мой первый вопрос в Stackoverflow. Я пытаюсь вызвать виджет в другом StatefulWidget, когда мы передаем его как параметр класса класса.

Итак, у меня есть этот пользовательский виджет:

class MyTextWidget extends StatelessWidget {

  final String text;

  MyTextWidget({ @required this.text });

  @override
  Widget build(BuildContext context) {
    return Text(this.text);
  }

}

, который я хочу использовать в другом виджете, например это (с передачей в параметре конструктора класса)

import 'package:myproject/MyTextWidget.dart';
.
.
.
// Passing widget like this
child: Example(display: MyTextWidget,text: this.widget.text);
.
.
.
// And use this widget like this
this.widget.display(text: this.widget.text);

это мой первый код:

class Example extends StatefulWidget {

  final Widget display;
  final String text;

  Example({ @required this.display, @required this.text });

  @override
  State<StatefulWidget> createState() {
    return ExampleState();
  }

}

class ExampleState extends State<Example> {

  @override
  Widget build(BuildContext context) {
      return this.widget.display(text: this.widget.text); // here we have error
  }

}

но у меня есть эта ошибка

The expression doesn't evaluate to a function, so it can't be invoked.dart(invocation_of_non_function_expression)

Я понимаю, что мне нужно сделать typedef для этой проблемы, поэтому я улучшаю код следующим образом:

typedef Widget DisplayType({ @required String text });

class Example extends StatefulWidget {

  final DisplayType display;
  final String text;

  Example({ @required this.display, @required this.text });

  @override
  State<StatefulWidget> createState() {
    return ExampleState();
  }

}

class ExampleState extends State<Example> {

  @override
  Widget build(BuildContext context) {
      return this.widget.display(text: this.widget.text);
  }

}

Наша ошибка исправлена, но когда я хочу передать MyTextWidget в другой виджет:

child: Example(display: MyTextWidget,text: this.widget.text);

Наконец я получаю эту ошибку:

The argument type 'Type' can't be assigned to the parameter type 'Widget Function({String text})'.dart(argument_type_not_assignable)

как я могу решить эту проблему?

Ответы [ 2 ]

0 голосов
/ 08 февраля 2020

Я думаю, вы хотите, чтобы display была функцией построителя, которая возвращает MyTextWidget.

import 'package:flutter/material.dart';

Future<void> main() async {
  return runApp(MyApp());
}

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

class MyHomePage extends StatelessWidget {
  @override
  Widget build(final BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Home")),
      body: Center(
        child: Example(
          display: ({@required final String text}) {
            assert(text != null);
            return MyTextWidget(text: text);
          },
          text: "some text",
        ),
      ),
    );
  }
}

class MyTextWidget extends StatelessWidget {
  final String text;

  MyTextWidget({@required this.text}) : assert(text != null);

  @override
  Widget build(final BuildContext context) {
    return Text(this.text);
  }
}

typedef Widget DisplayType({@required final String text});

class Example extends StatefulWidget {
  final DisplayType display;
  final String text;

  Example({
    @required this.display,
    @required this.text,
  })  : assert(display != null),
        assert(text != null);

  @override
  State<StatefulWidget> createState() {
    return ExampleState();
  }
}

class ExampleState extends State<Example> {
  @override
  Widget build(final BuildContext context) {
    return this.widget.display(text: this.widget.text);
  }
}
0 голосов
/ 08 февраля 2020

Вам не нужно передавать виджет вниз, просто импортируйте его в класс, который вы хотите использовать.

Когда вы хотите создать его экземпляр, вам нужно использовать скобки MyTextWidget().

Вам не нужно использовать this при вызове параметров, переданных в Stateful Widget, просто widget.text сработает.

Похоже, у вас возникли некоторые недоразумения относительно Flutter. Есть очень редкие случаи, когда вам нужно использовать this.

...