JSON文件在Flutter上无法加载

huangapple go评论102阅读模式
英文:

JSON file not loading on Flutter

问题

我是Flutter新手,目前卡在我的JSON文件内容无法在模拟器上显示。没有错误显示,但也没有内容。如果我直接在我的代码块中包含内容,它可以正常工作。我无法找出问题所在。

以下是我的代码:

main.dart 代码

import 'package:emailapp/messagelist.dart';
import 'package:flutter/material.dart';

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

class EmailApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
      home: MessageList(title: 'Muss Mailer APP'),
    );
  }
}

messagelist.dart

import 'dart:convert';

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

class MessageList extends StatefulWidget {
  final String title;

  const MessageList({Key key, this.title}) : super(key: key);

  @override
  State<StatefulWidget> createState() => _MessageListState();
}

class _MessageListState extends State<MessageList> {
  var messages = const [];

  Future loadMessageList() async {
    var content = await rootBundle.loadString('data/message.json');
    print(content);
    var collection = json.decode(content);

    setState(() {
      messages = collection;
    });
  }

  void initState() {
    loadMessageList();
    super.initState();
  }

  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: ListView.separated(
        separatorBuilder: (context, index) => Divider(),
        itemCount: messages.length,
        itemBuilder: (BuildContext context, int index) {
          var message = messages[index];

          return ListTile(
            isThreeLine: true,
            leading: CircleAvatar(child: Text('AJ')),
            title: Text(message['subject']),
            subtitle: Text(
              message['body'],
              maxLines: 2,
              overflow: TextOverflow.ellipsis,
            ),
          );
        },
      ),
    );
  }
}

message.json

[
  {
    "subject": "My First Message",
    "body": "Hello Form the other side of life fellas.. and happy to meet you guys"
  },
  {
    "subject": "My Second Message",
    "body": "Hello Form the other side of life fellas.. and happy to meet you guys"
  },
  {
    "subject": "My Third Message",
    "body": "Hello Form the other side of life fellas.. and happy to meet you guys"
  },
  {
    "subject": "My Fourth Message",
    "body": "Hello Form the other side of life fellas.. and happy to meet you guys"
  },
  {
    "subject": "My Fifth Message",
    "body": "Hello Form the other side of life fellas.. and happy to meet you guys"
  },
  {
    "subject": "My Sixth Message",
    "body": "Hello Form the other side of life fellas.. and happy to meet you guys"
  }
]

pubspec.yaml

assets:
  - data/message.json

希望这可以帮助你解决问题。

英文:

I am new to Flutter, am currently stuck with my JSON file content not populating on my emulator. It shows no error, yet not displaying. If I include the content directly in my codeblock, it works fine. I can't spot the issue.

Below are my codes:

main.dart code

import &#39;package:emailapp/messagelist.dart&#39;;
import &#39;package:flutter/material.dart&#39;;


void main() =&gt; runApp(EmailApp());

class EmailApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: &#39;Flutter Demo&#39;,
      theme: ThemeData(
      
        primarySwatch: Colors.green
      ),
      home: MessageList(title: &#39;Muss Mailer APP&#39;),
    );
  }
}

messagelist.dart

import &#39;dart:convert&#39;;

import &#39;package:flutter/material.dart&#39;;
import &#39;package:flutter/services.dart&#39;;

class MessageList extends StatefulWidget{

  final String title;

  const MessageList({Key key, this.title}) : super(key: key);

@override
State&lt;StatefulWidget&gt; createState()=&gt;_MessageListState();
}

class _MessageListState extends State&lt;MessageList&gt;{
var messages=const [];

Future loadMessageList()  async{
  var content=await rootBundle.loadString(&#39;data/message.json&#39;);
  print(content);
  var collection=json.decode(content);

setState(() {
 messages=collection; 
});
}
void initstate() {
  loadMessageList();
  super.initState();
}
   Widget build(BuildContext context) {
     return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
    
    body: ListView.separated(
      separatorBuilder: (context,index)=&gt;Divider(),

    itemCount: messages.length,

  itemBuilder: (BuildContext context, int index){
    var message=messages[index];
    
    return ListTile(
      isThreeLine: true,
      leading: CircleAvatar( child: Text(&#39;AJ&#39;),),
      title: Text(message[&#39;subject&#39;]),
      subtitle: Text(message[&#39;body&#39;],maxLines: 2, overflow: TextOverflow.ellipsis,),
      
      ) ;
  },
),
    

    );
  }

}

message.json

   [ {
        &quot;subject&quot;:&quot;My First Message&quot;,
  &quot;body&quot;:&quot;Hello Form the other side of life fellas.. and happy to meet you guys&quot;
  
      },
      {
        &quot;subject&quot;:&quot;My Second Message&quot;,
  &quot;body&quot;:&quot;Hello Form the other side of life fellas.. and happy to meet you guys&quot;
  
      },
      {
        &quot;subject&quot;:&quot;My Third Message&quot;,
  &quot;body&quot;:&quot;Hello Form the other side of life fellas.. and happy to meet you guys&quot;
  
      },
      {
        &quot;subject&quot;:&quot;My Fourth Message&quot;,
  &quot;body&quot;:&quot;Hello Form the other side of life fellas.. and happy to meet you guys&quot;
  
      },
      {
        &quot;subject&quot;:&quot;My Fifth Message&quot;,
  &quot;body&quot;:&quot;Hello Form the other side of life fellas.. and happy to meet you guys&quot;
  
      },
      {
        &quot;subject&quot;:&quot;My Sixth Message&quot;,
  &quot;body&quot;:&quot;Hello Form the other side of life fellas.. and happy to meet you guys&quot;
  
      }]

pubspec.yaml

  assets:
  #  - images/a_dot_burr.jpeg
  #  - images/a_dot_ham.jpeg
    - data/message.json

答案1

得分: 1

"It's just a spelling mistake. It's not initstate. Its initState (S is capital).

void initState() {
  loadMessageList();
  super.initState();
}
```"

<details>
<summary>英文:</summary>

It&#39;s just a spelling mistake. It&#39;s not `initstate`. Its `initState` (**S** is capital).

    void initState() {
      loadMessageList();
      super.initState();
    }


</details>



# 答案2
**得分**: 1

我建议进行以下更改,以解决一些基本问题:

- 在`initState`方法中添加`@override`注释,并在`initState`方法的名称中使用`S`,如`@Crazy Lazy Cat`所建议的:
```dart
@override
void initState() {
  loadMessageList();
  super.initState();
}
  • 移除initState内部使用setState的部分,不建议在尚未构建的小部件上设置状态:
Future loadMessageList() async {
  // 其他所有内容保持不变
  messages = collection; 
}
  • 从消息中移除const [],因为它在initState中已被替换。

  • 由于loadMessageList是异步方法,您应该使用FutureBuilder来实现此目的:

FutureBuilder(
    future: loadMessageList,
    builder: (context, snapshot) => snapshot.hasData ? your_widget() : Container(),
),

your_widget()小部件指的是build方法中的ListView.separated小部件。

在定义ListView.separated代码之前创建var messages = snapshot.data;

为了使此工作正常,您需要更改loadMessageList中的代码:

Future loadMessageList() async {
  // 其他所有内容保持不变
  // messages = collection;
  return collection;
}

现在不需要全局的messages变量了。

英文:

I would suggest making the following changes, to resolve some basic issues:

  • add Override notation to initState and use S in initState name:
    as suggested by @Crazy Lazy Cat
@override
void initState() {
  loadMessageList();
  super.initState();
}
  • remove the use of setState inside the initState, it is not recommended to set state of a widget which has not been built yet:
Future loadMessageList()  async{
  // everything else, as it is
  messages = collection; 
}
  • remove const [] from the messages, since it is replaced in the initState anyways.

  • since the loadMessageList is async method you should use FutureBuilder for this purpose:

  FutureBuilder(
      future: loadMessageList,
      builder: (context, snapshot) =&gt; snapshot.hasData ? your_widget() : Container(),
  ),

your_widget() widget refers to the ListView.separated widget in the build method.

create var messages = snapshot.data; before defining the ListView.separated code.

for this to work you need to change the code in loadMessageList:

Future loadMessageList()  async {
  // everything else, as it is
  //messages = collection;
  return collection;
}

No need of global messages variable now.

huangapple
  • 本文由 发表于 2020年1月6日 22:20:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/59613709.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定