将json数据发送到新屏幕Flutter

时间:2020-11-10 12:51:52

标签: json class flutter dart future

我想将json对象发送到新的dart文件并在其中使用它。 在第一个文件中是一个列表视图,当您点击列表项时,将调用secondscreen(jobdetail),并通过该调用将所有json信息发送至secondscreen(jobdetail)并将其打印到控制台中。 如果您有其他更好的方法,则不必纠正我的方法。

这是我尝试的方式: 第一个屏幕:

onTap: () {
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => JobDetail(),
                  // Pass the arguments as part of the RouteSettings. The
                  // DetailScreen reads the arguments from these settings.
                  settings: RouteSettings(
                    arguments: jsonData[index],
                  ),
                ),
              );
            },

第二屏(作业详细信息):

class JobDetail extends StatelessWidget {

@override
Widget build(BuildContext context) {
final jsonData = ModalRoute.of(context).settings.arguments;
print(jsonData.titel);
return new MaterialApp(
  debugShowCheckedModeBanner: false,
  title: 'Flutter App with MYSQL',
  home: new MyHomePage(),

);
}
}

Future<dynamic> senddata() async {
final response = await http.post(
  "https://www.falseurl.php", body: {
"status": "0",
"Id": "5",
"JobBlocksInProres": "0",
"IdJB": jsonData.titel,
});

var datauser = json.decode(response.body);

String jsonsDataString = datauser.toString();
dynamic Data = jsonDecode(jsonsDataString);

print(Data);


return Data;
}

我收到此错误:

lib/JobDetail.dart:15:20: Error: The getter 'titel' isn't defined for the class 'Object'.
 - 'Object' is from 'dart:core'.
Try correcting the name to the name of an existing getter, or defining a getter or field     named 'titel'.
print(jsonData.titel);
               ^^^^^
lib/JobDetail.dart:31:13: Error: Getter not found: 'jsonData'.
"IdJB": jsonData.id,
        ^^^^^^^^
lib/JobDetail.dart:37:11: Error: Can't declare 'jsonData' because it was already used in this scope.
  dynamic jsonData = jsonDecode(jsonsDataString);
      ^^^^^^^^
lib/JobDetail.dart:31:13: Context: Previous use of 'jsonData'.
"IdJB": jsonData.id,
        ^^^^^^^^
lib/JobDetail.dart:39:9: Error: Getter not found: 'jsonData'.
  print(jsonData);
    ^^^^^^^^
lib/JobDetail.dart:42:10: Error: Getter not found: 'jsonData'.
  return jsonData;

感谢您的回答

新代码 第一个屏幕:

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

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

import 'package:navigation/JobDetail.dart';

class Muensterboerse extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
  return new MaterialApp(
  debugShowCheckedModeBanner: false,
  title: 'Flutter App with MYSQL',
  home: new MyHomePage(),

  );
  }
  }

Future<dynamic> senddata() async {

  final response = await http.post(
      "https://www.falseurl.php", body: {
      "status": "0",
  });


  var datauser = json.decode(response.body);

  String jsonsDataString = datauser.toString();
  dynamic jsonData = jsonDecode(jsonsDataString);

  print(jsonData);


  return jsonData;
}

class Job {
  final String title;
  // Other properties

  Job({this.title});

 factory Job.fromJSON(Map<String, dynamic> map) {
    return Job(
      title: map['title'],
    );
  }
}

class JobDetailScreenArg {
  final Job job;

  JobDetailScreenArg(this.job);
}

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

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {

  dynamic jsonData;


  callSendData() async {
      jsonData = await senddata();
      setState(() {});
  }

//lol
  @override
  void initState() {
    callSendData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: jsonData == null
            ? Center(child: CircularProgressIndicator())
            : ListView.builder(
            padding: const EdgeInsets.all(16.0),
            itemCount: jsonData == null ? 0 : jsonData.length,
            itemBuilder: (context, index) {
              return ListTile(

                leading: CircleAvatar(
                  backgroundImage:     NetworkImage('https://kinsta.com/de/wp-content/uploads/sites/5/2019/09/wordpress-loggst-url-1024x512.jpg'),
              radius: 27,
            ),

            title: Text(
              jsonData[index]["titel"],
            ),
            subtitle: Text(jsonData[index]["nam_ersteller"]),
            trailing: Text(
              '25 Km',
              style: TextStyle(color: Colors.grey,
                fontSize: 12,
                decoration: TextDecoration.none,
                fontFamily: 'Roboto',),

            ),
            onTap: () {

              JobDetailScreenArg arg = JobDetailScreenArg(jsonData);
              Navigator.of(context).pushNamed('/JobDetailScreen', arguments: arg);

            },

          );
          // return _buildRow(data[index]);
        }));
  }
}

第二屏幕:

   import 'package:flutter/material.dart';

     import 'package:navigation/Muensterboerse.dart';

   class JobDetailScreen extends StatefulWidget {
     final Job job;

     JobDetailScreen(this.job);

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

   class _JobDetailScreenState extends State<JobDetailScreen> {
     @override
     Widget build(BuildContext context) {
       return Container(
         child: Text('${widget.job.title}'),
       );
     }
   }

新错误:

type 'List<dynamic>' is not a subtype of type 'Job'

2 个答案:

答案 0 :(得分:1)

首先,请检查以下内容:

  • 在第一个屏幕上,我觉得jsonData被解码为dynamic类型。如果您的jsonString是有效的JSON,请将其解码为Map<String, dynamic>。例如Map<String, dynamic> data = jsonDecode(jsonString)。请注意FormatException & TypeError
  • 此外,如果您的jsonString包含项列表(job json对象),则按如下所示转换列表并将其项映射到您自己的Dart对象中。
var items = data['jobs'] as List;
List<Job> jobs = items.map<Job>((jobItem) => Job.fromJSON(jobItem)).toList();
  • 您的Job Dart对象可能如下所示
class Job {
  final String title;
  // Other properties

  Job({this.title});

  factory Job.fromJSON(Map<String, dynamic> map) {
    return Job(
      title: map['title'],
    );
  }
}

接下来,我建议您使用以下摘录作为一种从途中向另一个发送数据的好方法。

为路由参数数据创建参数类

class JobDetailScreenArg {
  final Job job;

  JobDetailScreenArg(this.job);
}
MaterialApp(
    title: 'Jobs',
    // Start the app with the "/" named route. In this case, the app starts
    // on the FirstScreen widget.
    initialRoute: '/',
    onGenerateRoute: (RouteSettings settings) {
      switch(settings.name) {
        case '/jobDetail':
         JobDetailScreenArg args = settings.arguments;
         return _buildRoute(settings, JobDetailScreen(args.job));
        case '/':
         return _buildRoute(settings, JobsScreen());
      }
    }
  )



Route _buildRoute(RouteSettings settings, Widget screen) {
    return MaterialPageRoute(
      settings: settings,
      builder: (context) => screen,
    );
  }

职位列表屏幕

onTap: () {
  // job - tapped item
  JobDetailScreenArg arg = JobDetailScreenArg(job);
  Navigator.of(context).pushNamed('/jobDetail', arguments: arg);
}

详细信息屏幕

class JobDetailScreen extends StatefulWidget {
  final Job job;
  
  JobDetailScreen(this.job);

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

class _JobDetailScreenState extends State<JobDetailScreen> {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text('${widget.job.title}'),
    );
  }
}

答案 1 :(得分:0)

我不会说问题是“如何将信息发送到另一个文件”。我要说的是“如何将信息从一个小部件发送到另一个小部件”。

为此,您可以在JobDetails小部件中添加一个job属性(我想它叫做Job),然后像信息一样发送信息。

第一个屏幕:

ListView.builder(
  itemCount: jobs.length,
  itemBuilder: (BuildContext context, int index) {
    var currentJob = jobs[index];
    return JobDetail(currentJob);
  }
);

第二屏幕:

class JobDetail extends StatelessWidget {
  // Here you add the constructor and the parameter
  Job job;

  JobDetail(this.job)

我的语法可能不正确