Home > front end >  The argument type 'Widget Function(BuildContext)' can't be assigned to the parameter
The argument type 'Widget Function(BuildContext)' can't be assigned to the parameter

Time:04-02

I am trying to implement the following code for a Quiz game created in flutter

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:widget_quiz/model/model.dart';
import 'package:widget_quiz/pages/quiz_page/selections.dart';

import 'model.dart';
import 'progress.dart';
import 'question.dart';
import 'result_presenter.dart';

class QuizPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      builder: (context) => Model(
        quizLoader: Provider.of<QuizLoader>(context, listen: false),
      ),
      create: (BuildContext context) {  },
      child: const _Page(),
    );
  }
}

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

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

class __PageState extends State<_Page> {
  Model get _model => Provider.of<Model>(context, listen: false);
  final _resultPresenter = ResultPresenter();

  static const double _horizontalMargin = 16;

  @override
  void initState() {
    super.initState();

    _model.answered.listen((correct) async {
      await _resultPresenter.show(context, model: _model, correct: correct);
      _model.next();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Widget Quiz'),
      ),
      body: _buildBody(),
    );
  }

  Widget _buildBody() {
    final model = Provider.of<Model>(context);
    return SafeArea(
      child: AnimatedSwitcher(
        duration: const Duration(milliseconds: 200),
        child: model.quizListLoaded
            ? model.hasQuiz ? _buildQuiz() : _buildResult()
            : const Center(child: CircularProgressIndicator()),
      ),
    );
  }

  Widget _buildQuiz() {
    return Column(
      children: const [
        Progress(),
        Divider(
          indent: _horizontalMargin,
          endIndent: _horizontalMargin,
          height: 0,
        ),
        Expanded(
          child: SingleChildScrollView(
            padding: EdgeInsets.all(_horizontalMargin),
            physics: AlwaysScrollableScrollPhysics(),
            child: Question(),
          ),
        ),
        Padding(
          child: Selections(),
          padding: EdgeInsets.symmetric(horizontal: _horizontalMargin),
        ),
      ],
    );
  }

  Widget _buildResult() {
    final model = Provider.of<Model>(context);
//    model
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Text(
            '⭕️ ${model.progress.where((p) => p == ProgressKind.correct).length} / 10',
            style: const TextStyle(fontSize: 32),
          ),
          const SizedBox(height: 8),
          Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: model.progress
                .asMap()
                .map((index, p) => MapEntry(
                    index,
                    Text(
                        '${p == ProgressKind.correct ? '⭕️' : '❌'} ${model.quizList[index].correct.name}')))
                .values
                .toList(),
          ),
          const SizedBox(height: 8),
          RaisedButton(
            child: const Text('TRY AGAIN'),
            onPressed: model.load,
          )
        ],
      ),
    );
  }
}


BUT I get the following errors

1/ error: The return type 'Model' isn't a 'Widget', as required by the closure's context. (return_of_invalid_type_from_closure at [widget_quiz] lib\pages\quiz_page\quiz_page.dart:15)

2/error: The argument type 'Widget Function(BuildContext)' can't be assigned to the parameter type 'Widget Function(BuildContext, Widget)'. (argument_type_not_assignable at [widget_quiz] lib\pages\quiz_page\quiz_page.dart:15)

what is the solutions?

CodePudding user response:

First Issue

parameter builder in ChangeNotifierProvider need a function widget with type

Widget Function(BuildContext context, Widget? child)

So, change this line

builder: (context) => Model(

with

builder: (context, child) => Model(

Second Issue

You just need to return a Widget in the function. child is a Widget, so you can return the child or another widget.

builder: (context, child) {
  // Your code
  return child;
}
  • Related