在颤振地图功能在列小部件中不起作用

Posted

技术标签:

【中文标题】在颤振地图功能在列小部件中不起作用【英文标题】:In flutter map function does not working in column widget 【发布时间】:2021-05-13 14:58:01 【问题描述】:

我正在尝试在列小部件内动态创建行小部件。我是新手,我尽力了,但仍然未能解决问题。我想请你帮我解决这个问题。我添加了所有我尝试过的东西。非常感谢

我的杰森


    "status": true,
    "data": 
        "id": 1,
        "image": "https://img.taste.com.au/fruCLEZM/taste/2019/08/chicken-karahi-153167-2.jpg",
        "calories": 100,
        "ingredients_count": 5,
        "serve": 1,
        "views": 1,
        "time": 1,
        "translate": 
            "post_title": "Chicken Karahi",
            "post_description": "spicy and tasteful chicken karahi."
        ,
        "ingredients": [
            
                "name": "yogurt",
                "quantity": "1 cup",
                "image": "https://www.archanaskitchen.com/images/archanaskitchen/BasicRecipes_HOW_TO/How_To_Make_Fresh_Homemade_Yogurt_Curd_400.jpg"
            ,
            
                "name": "red chilli",
                "quantity": "100 gram",
                "image": "https://ik.imagekit.io/91ubcvvnh3k/tr:w-500/https://www.planetorganic.com//images/products/medium/26148.jpg"
            
        ]
    

Image for refrence

我面临以下两个错误,

Another exception was thrown: type '(dynamic) => dynamic' is not a subtype of type '(Ingredient) => Widget' of 'f'

type 'Container' is not a subtype of type 'List<Widget>'

在我的 statefull 类中,我有以下内容

var posts;
bool _load = false;
void initState()      
  super.initState();
  getRecipeById().then((value) => 
    setState(()
      posts = value;
    )
  );

通过这种方法,我从 api 获取数据

getRecipeById() async 
      String url = 'http://www.xxxxx.com/xxxxx/in.php';
      Map<String, String> requestHeaders = 
        'Content-type': 'application/json',
        'Accept': '*/*',
      ;
      final json = 
        "by_post_id": 'yes',
        "post_id":'$widget.postId'
      ;
      http.Response response = await http.post(url, body: json);
      if(response.statusCode == 200)
        setState(() 
          _load = true;
        );
      
      var jsonResponse = jsonDecode(response.body);
      posts = RecipeModel.fromJson(jsonResponse['data']);
      return posts;
    

以下是我的构建小部件

Widget build(BuildContext context) 
  final ingredientsList = Container(
    width: MediaQuery.of(context).size.width,
    padding: EdgeInsets.only(left: 1.0, right: 25.0),
    margin: const EdgeInsets.only(bottom: 20.0),
    child: Container(
      child: Column(
        children: (_load == false) ? Container(child:Text("loading..")) : posts.ingredients.map<Widget>((data) => 
          ingredientsRow(data.name, data.quantity, data.image)
        ).toList(),
      ),
    ),
  );

  return SafeArea(
      top: true,
      child: Scaffold(
      body: Directionality(
        textDirection: TextDirection.ltr,
        child: SingleChildScrollView(
          child: (_load == false) ? Container(
            alignment: Alignment.center,
            child: Text("loading now..")
            ) :
          Column(
            children: <Widget>[
              ingredientsList,

            ],
          ),
        ),
      ),
    )
  );

以下是我想在地图中使用的功能

ingredientsRow(name, quantity, image)
    
      return Row(
        mainAxisAlignment: MainAxisAlignment.start,
        children: [
              Expanded(
                flex: 2, // 20%
                child: Container(
                  alignment: Alignment.center,
                    child: Image.network(image,
                    height: 45,
                    ) 
                ),
              ),
              Expanded(
                flex: 4, // 60%
                child: Container(
                  child:Text(
                    name,
                    style: TextStyle(
                      color: Color(0xff41453c), 
                      fontSize: 15,
                      fontWeight: FontWeight.w400
                    ),
                  )
                ),
              ),
              Expanded(
                flex: 4, // 20%
                child: Container(
                  alignment: Alignment.center,
                  child:Text(
                    quantity,
                    style: TextStyle(
                      color: Color(0xff41453c), 
                      fontSize: 15,
                      fontWeight: FontWeight.w400
                    ),
                  )
                ),
              )
            ],
        );
    

这是我的数据模型类

class RecipeModel
  final int id;
  final String image;
  final List<Ingredient> ingredients;

  RecipeModel(this.id, this.image, this.ingredients);

  factory RecipeModel.fromJson(Map<String, dynamic> parsedJson)

    var list = parsedJson['ingredients'] as List;
    print(list.runtimeType);
    List<Ingredient> ingredientsList = list.map((i) => Ingredient.fromJson(i)).toList();
    return RecipeModel(
      id: parsedJson['id'],
      image: parsedJson['image'],
      ingredients: ingredientsList

    );
  


class Ingredient 
  final String name;
  final String quantity;
  final String image;

  Ingredient(this.name, this.quantity, this.image);

  factory Ingredient.fromJson(Map<String, dynamic> parsedJson)
   return Ingredient(
     name:parsedJson['name'],
     quantity:parsedJson['quantity'],
     image:parsedJson['image']
   );
  

【问题讨论】:

嗨,有趣,不确定这是否有助于解决该错误***.com/questions/49603021/… 在哪一行你有这个错误Another exception was thrown: type '(dynamic) =&gt; dynamic' is not a subtype of type '(Ingredient) =&gt; Widget' of 'f' 【参考方案1】:

最好的方法是使用FutureBuilder。

我检查了您的代码,主要更改了 4 件事:

1- 我在 FutureBuilder 中使用了一种方法,它就是为此目的而构建的。

2- 移除了 componentsList 变量,并将其代码移至名为 _buildIngredientList 且返回类型为 Widget 的函数中。

3- 删除布尔变量,因为使用 FutureBuilder 不再需要它。

4- 将返回类型“Widget”添加到 ingredientsRow 函数中,否则会引发类型错误。

查看以下代码:

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

import 'package:***samples/models.dart';

void main() => runApp(
  MaterialApp(home: HomePage(),
    theme: ThemeData.fallback(),
  ),
);
class HomePage extends StatefulWidget 

  @override
  _HomePageState createState() => _HomePageState();


class _HomePageState extends State<HomePage> 
  var posts;
  ///3 - Remove bool

  void initState() 
    super.initState();
    getRecipeById().then((value) => 
      setState(()
        posts = value;
      )
    );
  

  Widget build(BuildContext context) 
    return SafeArea(
        top: true,
        child: Scaffold(
          body: Directionality(
            textDirection: TextDirection.ltr,
            child: SingleChildScrollView(
              child:
              FutureBuilder( ///1
                future: getRecipeById(),
                builder: (context, snapshot) 
                  if(snapshot.connectionState == ConnectionState.done) 
                    return Column(
                      children: <Widget>[
                        _buildIngredientList(),
                      ],
                    );
                   else 
                    return Container(
                        alignment: Alignment.center,
                        child: Text("loading now..")
                    );
                  
                
              ),
            ),
          ),
        )
    );
  

  Widget _buildIngredientList()  ///2
    return Container(
      width: MediaQuery.of(context).size.width,
      padding: EdgeInsets.only(left: 1.0, right: 25.0),
      margin: const EdgeInsets.only(bottom: 20.0),
      child: Container(
        child: Column(
          children: posts.ingredients.map<Widget>((data) =>
              ingredientsRow(data.name, data.quantity, data.image)
          ).toList(),
        ),
      ),
    );
  
  ///4
  Widget ingredientsRow(name, quantity, image) 
    return Row(
      mainAxisAlignment: MainAxisAlignment.start,
      children: [
        Expanded(
          flex: 2, // 20%
          child: Container(
              alignment: Alignment.center,
              child: Image.network(image,
                height: 45,
              )
          ),
        ),
        Expanded(
          flex: 4, // 60%
          child: Container(
              child:Text(
                name,
                style: TextStyle(
                    color: Color(0xff41453c),
                    fontSize: 15,
                    fontWeight: FontWeight.w400
                ),
              )
          ),
        ),
        Expanded(
          flex: 4, // 20%
          child: Container(
              alignment: Alignment.center,
              child:Text(
                quantity,
                style: TextStyle(
                    color: Color(0xff41453c),
                    fontSize: 15,
                    fontWeight: FontWeight.w400
                ),
              )
          ),
        )
      ],
    );
  

  getRecipeById() async 
    ///I've pasted the json as literal here because otherwise I couldn't make it run on my side.
    var jsonResponse = jsonDecode('''
    "status": true,
    "data": 
        "id": 1,
        "image": "https://img.taste.com.au/fruCLEZM/taste/2019/08/chicken-karahi-153167-2.jpg",
        "calories": 100,
        "ingredients_count": 5,
        "serve": 1,
        "views": 1,
        "time": 1,
        "translate": 
            "post_title": "Chicken Karahi",
            "post_description": "spicy and tasteful chicken karahi."
        ,
        "ingredients": [
            
                "name": "yogurt",
                "quantity": "1 cup",
                "image": "https://www.archanaskitchen.com/images/archanaskitchen/BasicRecipes_HOW_TO/How_To_Make_Fresh_Homemade_Yogurt_Curd_400.jpg"
            ,
            
                "name": "red chilli",
                "quantity": "100 gram",
                "image": "https://ik.imagekit.io/91ubcvvnh3k/tr:w-500/https://www.planetorganic.com//images/products/medium/26148.jpg"
            
        ]
    
''');
    posts = RecipeModel.fromJson(jsonResponse['data']);
    return posts;
  

【讨论】:

以上是关于在颤振地图功能在列小部件中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

颤振补间基本动画在“FutureBuilder”中不起作用

为啥这个切换按钮在颤振 - 飞镖中不起作用?

执行 XCUITest 时,Tap 方法在今日视图中不起作用

滑动以返回在 ios 中的颤振 webview 中不起作用

颤振热重新加载在android studio(mac)中不起作用

谷歌字体包在颤振中不起作用