当前位置: 首页 > 知识库问答 >
问题:

如何将json数据传递给Flatter小部件

何雅惠
2023-03-14

我是Flutter和Dart的新手。我有一些来自基于api json的数据,数据的变量称为data。我从官方flutter留档中获取了这个示例代码,我希望能够使用data变量并替换字符串文本,如下所示:

return new Card(
 child: new Column(
   mainAxisSize: MainAxisSize.min,
   children: <Widget>[
     const ListTile(
       leading: const Icon(Icons.album),
       title: const Text(data[index]['name']),
       subtitle: const Text('Music by Julie Gable. Lyrics by Sidney Stein.'),
     ),
     new ButtonTheme.bar( // make buttons use the appropriate styles for cards
       child: new ButtonBar(
         children: <Widget>[
           new FlatButton(
             child: const Text('BUY TICKETS'),
             onPressed: () { /* ... */ },
           ),
           new FlatButton(
             child: const Text('LISTEN'),
             onPressed: () { /* ... */ },
           ),
         ],
       ),
     ),
   ],
 ),
);

但是,我在第行标题中遇到了一个错误:const Text(data[index][“name]),,错误是类型常量创建的参数必须是常量表达式。此错误来自Android Studio本身(版本3.2)

但当我使用这段代码(摘自youtube课程)时,它运行良好:

return new Container(
  child: new Column(
    crossAxisAlignment: CrossAxisAlignment.stretch,
    children: <Widget>[
      new Card(
          child: new Padding(
            padding: const EdgeInsets.all(16.0),
            child: new Container(
                child: Text(data[index]['name'],
                    style: TextStyle(
                        fontSize: 16.0, color: Colors.black54))),
          )),
      new Card(
        child: new Padding(
            padding: const EdgeInsets.all(16.0),
            child: new Container(
              child: Text(data[index]['description'],
                  style: TextStyle(
                      fontSize: 16.0, color: Colors.redAccent)),
            )),
      )
    ],
  ),
);

如何使用第一个代码示例而不出现任何错误?谢谢

更新:这是完整的代码

import 'dart:async';
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or press Run > Flutter Hot Reload in IntelliJ). Notice that the
        // counter didn't reset back to zero; the application is not restarted.
        primarySwatch: Colors.green,
      ),
      home: new MyHomePage(title: 'Flutter App'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  // This widget is the home page of your application. It is stateful, meaning
  // that it has a State object (defined below) that contains fields that affect
  // how it looks.

  // This class is the configuration for the state. It holds the values (in this
  // case the title) provided by the parent (in this case the App widget) and
  // used by the build method of the State. Fields in a Widget subclass are
  // always marked "final".

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  
  List data;
  
  Future<String> getData() async {
    http.Response response = await http.get(
      Uri.encodeFull('https://dummyapicall.api'),
      headers: {
        "Accept": "application/json",
      }
    );

    this.setState(() {
      data = json.decode(response.body);
    });

    return 'Success!';
  }

  @override
  void initState() {
    super.initState();
    this.getData();
  }
  
  @override
  Widget build(BuildContext context) {
    // This method is rerun every time setState is called, for instance as done
    // by the _incrementCounter method above.
    //
    // The Flutter framework has been optimized to make rerunning build methods
    // fast, so that you can just rebuild anything that needs updating rather
    // than having to individually change instances of widgets.
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new ListView.builder(
          itemCount: data == null ? 0 : data.length,
          itemBuilder: (BuildContext context, int index) {
//            return new Container(
//              child: new Column(
//                crossAxisAlignment: CrossAxisAlignment.stretch,
//                children: <Widget>[
//                  new Card(
//                      child: new Padding(
//                        padding: const EdgeInsets.all(16.0),
//                        child: new Container(
//                            child: Text(data[index]['name'],
//                                style: TextStyle(
//                                    fontSize: 16.0, color: Colors.black54))),
//                      )),
//                  new Card(
//                    child: new Padding(
//                        padding: const EdgeInsets.all(16.0),
//                        child: new Container(
//                          child: Text(data[index]['description'],
//                              style: TextStyle(
//                                  fontSize: 16.0, color: Colors.redAccent)),
//                        )),
//                  )
//                ],
//              ),
//            );


            return new Card(
              child: new Column(
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  const ListTile(
                    leading: const Icon(Icons.album),
                    title: const Text(data[index]['name']),
                    subtitle: const Text('Music by Julie Gable. Lyrics by Sidney Stein.'),
                  ),
                  new ButtonTheme.bar( // make buttons use the appropriate styles for cards
                    child: new ButtonBar(
                      children: <Widget>[
                        new FlatButton(
                          child: const Text('BUY TICKETS'),
                          onPressed: () { /* ... */ },
                        ),
                        new FlatButton(
                          child: const Text('LISTEN'),
                          onPressed: () { /* ... */ },
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            );
            
          },
      ),
//      floatingActionButton: new FloatingActionButton(
//        onPressed: _incrementCounter,
//        tooltip: 'Increment',
//        child: new Icon(Icons.add),
//      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

共有2个答案

段干兴业
2023-03-14

只需在ListTile的两个位置删除const关键字。

它们不能是常量,因为您在文本小部件中包含一个变量(数据)。

      children: <Widget>[
        ListTile(
          leading: const Icon(Icons.album),
          title: Text(data[index]['name']),
          subtitle: const Text(
              'Music by Julie Gable. Lyrics by Sidney Stein.'),
        ),
        .....
马祺
2023-03-14

由于文本小部件定义为const,小部件的标签或属性也应为const,因为您的数据是动态的,而不是编译时的const,您将看到错误。

const Widget必须从编译时可以计算的数据创建。const对象无权访问您在运行时需要计算的任何内容。1 2是有效的const表达式,但new DateTime.now()不是。

发件人:有关常量、静态、最终的详细信息

 类似资料:
  • 我有以下运行时生成的json数组。因此,名称/数据对的数量有所不同。 我想将这些数据传递到highcharts系列中。 这就是我目前的做法。 但是如果数组中元素的数量改变了,这就不起作用了。我该如何解决这个问题?演示代码会对我有帮助。 我已经考虑了以下问题,但我无法解决这个问题。 动态添加到高图表 海图系列数据阵列

  • 如果需要与特定的应用编程接口/硬件组件交互,您将如何将信息从Flutter传递回Android/Native代码? 是否有任何事件通道可以以其他方式或类似于回调的方式发送信息? platform_channel文档指出,“方法调用也可以反向发送,平台充当Dart中实现的方法的客户端。quick_actions插件就是一个具体的例子。”在这种情况下,我看不出本机是如何接收到来自Flatter的消息的

  • 问题内容: 在Tkinter中是否可以将事件直接传递给父窗口小部件? 我有一个画布,该画布被其他画布的网格覆盖(是复数吗?),我使用方法添加了该画布。我希望某些事件(例如鼠标释放事件)由父画布处理。 如果仅将事件绑定到父方法,则和坐标相对于捕获事件的子画布而言。 问题答案: Tkinter不会将事件传递给父窗口小部件。但是,您可以通过使用绑定标签(或“ bindtags”)来模拟效果。 我能给出的

  • 我正在使用Speech_to_文本包将语音识别结果存储在一个字符串变量中,以后可以用于不同的目的,到目前为止,我只想在屏幕上显示该字符串。我想实现与Whatsap录制类似的功能,因此我使用启动录制和停止录制。 OnLongPress和OnLongPressUp分别调用属于不同类的方法。 我认为我只需要将方法分配给主小部件中的Text变量 给定方法返回所需的字符串 但是这种方法导致了一个redScr

  • 作为React课程的一部分,我正在制作一个虚拟电子商店,并希望将产品从一个组件的状态传递到功能组件并在那里显示产品属性。如何将数据从状态传递到无状态组件? 我设置了一个组件ProductList,它存储产品(从api获取)和ProductDetail,它应该显示详细信息(通过id找到产品并显示它的描述、img等)。我设置了一个pp.js,它有两个路由-列表和详细信息。 pp.js: Product

  • 很新的反应。。。 我试图循环我的this.props.children,以便向他们传递一个在我的父项中定义的字符串。。。在没有在render方法中定义这些子对象的情况下,这是可能的吗? OwnRenderer应该将道具字符串传递给它的所有子级。。。OwnRenderer不知道要渲染哪个孩子,因此无法通过“”直接传递道具。。。 我试着绕过孩子们直接传递那根绳子,但不幸的是,这不起作用。 不知怎的,它