从 mysql 获取数据到 StreamBuilder Flutter

Posted

技术标签:

【中文标题】从 mysql 获取数据到 StreamBuilder Flutter【英文标题】:Geting data from mysql to StreamBuilder Flutter 【发布时间】:2020-08-08 16:40:17 【问题描述】:

我有一个任务,我必须从 mysql 服务器获取数据并将其传递给 StreamBuilder,我试图使用我们在 firebase 中使用它的同一个类,现在我在传递我的数据时遇到问题已经将它从服务器带到 StreamBuilder 中,我记得我必须使用不同类型的快照,任何帮助。

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

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

class MyApp extends StatelessWidget 
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      title: 'Flutter Server',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.pink,
      ),
      home: MyHomePage(title: 'Flutter Server App'),
    );
  


class MyHomePage extends StatefulWidget 
  MyHomePage(Key key, this.title) : super(key: key);
  final String title;

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


class _MyHomePageState extends State<MyHomePage> 
  get documents => null;




  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        centerTitle: true,
      ),
    );
  

  Future getData() async
    var url = 'https://milk-white-reveille.000webhostapp.com/get.php';
    http.Response response = await http.get(url);
    var data = jsonDecode(response.body);
    print(data.toString());


  

  @override
  void initState() 
    getData();
  


class BookList extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return new StreamBuilder(
      stream: _MyHomePageState.getData().snapshot(),
      builder: (BuildContext context, AsyncSnapshot<_MyHomePageState> snapshot) 
        if (snapshot.hasData) return new Text('Loading...');
        return new ListView(
          children: snapshot.data.documents.map((document) 
            return new ListTile(
              title: new Text(document['title']),
              subtitle: new Text(document['type']),
            );
          ).toList(),
        );
      ,

    );

  


新代码是这样的

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

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

class MyApp extends StatelessWidget 
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      title: 'Flutter Server',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.pink,
      ),
      home: MyHomePage(title: 'Flutter Server App'),
    );
  


class MyHomePage extends StatefulWidget 
  MyHomePage(Key key, this.title) : super(key: key);
  final String title;

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


class _MyHomePageState extends State<MyHomePage> 
  StreamController _streamController = StreamController();
  Timer _timer;
  var data;

  Future getData() async 
    var url = 'https://milk-white-reveille.000webhostapp.com/get.php';
    http.Response response = await http.get(url);


    String jsonsDataString = response.body.toString(); // toString of Response's body is assigned to jsonDataString
    data = jsonDecode(jsonsDataString);
    print(data.toString());
    //Add your data to stream
    _streamController.add(data);
  

  @override
  void initState() 
    getData();

    //Check the server every 5 seconds
    _timer = Timer.periodic(Duration(seconds: 5), (timer) => getData());

    super.initState();
  

  @override
  void dispose() 
    //cancel the timer
    if (_timer.isActive) _timer.cancel();

    super.dispose();
  
  @override
  Widget build(BuildContext context) 
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Home"),
      ),
      body: new _MySql()

          );

  




class _MySql extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return Scaffold(
      body: StreamBuilder(
        stream: _MyHomePageState()._streamController.stream,
        builder: (BuildContext context, AsyncSnapshot snapshot) 
          if (snapshot.hasData)
            return ListView(
              children: snapshot.data((data) 
                return ListTile(
                  title: Text(data['title']),
                  subtitle: Text(data['type']),
                );
              ).toList(),
            );
          return CircularProgressIndicator();
        ,
      ),
    );
  

但在手机屏幕加载...出现 这个来自终端 E/flutter (10194): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: FormatException: Unexpected character (at character 1) E/flutter (10194): connected"title":"maen","type":"dev"

【问题讨论】:

那么您的具体问题是什么?请显示一些错误消息或其他内容。 现在将数据从快照传递到列表中没有错误。 【参考方案1】:

如果您想定期与 StreamBuilder 一起使用它;

import 'dart:async';

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

class MyApp extends StatelessWidget 
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      title: 'Flutter Server',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.pink,
      ),
      home: MyHomePage(title: 'Flutter Server App'),
    );
  


class MyHomePage extends StatefulWidget 
  MyHomePage(Key key, this.title) : super(key: key);
  final String title;

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


class _MyHomePageState extends State<MyHomePage> 
  StreamController _streamController = StreamController();
  Timer _timer;

  Future getData() async 
    var url = 'https://milk-white-reveille.000webhostapp.com/get.php';
    http.Response response = await http.get(url);
    var data = jsonDecode(response.body);

    //Add your data to stream
    _streamController.add(data);
  

  @override
  void initState() 
    getData();

    //Check the server every 5 seconds
    _timer = Timer.periodic(Duration(seconds: 5), (timer) => getData());

    super.initState();
  

  @override
  void dispose() 
    //cancel the timer
    if (_timer.isActive) _timer.cancel();

    super.dispose();
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        centerTitle: true,
      ),
      body: StreamBuilder(
        stream: _streamController.stream,
        builder: (BuildContext context, AsyncSnapshot snapshot) 
          if (snapshot.hasData)
            return ListView(
              children: snapshot.data.map((document) 
                return ListTile(
                  title: Text(document['title']),
                  subtitle: Text(document['type']),
                );
              ).toList(),
            );
          return Text('Loading...');
        ,
      ),
    );
  

【讨论】:

【参考方案2】:

您应该使用FutureBuilder 而不是StreamBuilder。如果您不想定期检查服务器,则不需要使用StreamBuilder 从服务器获取数据。 (如果您想定期使用它并与 StreamBuilder 一起查看我的下一个答案);

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

class MyApp extends StatelessWidget 
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      title: 'Flutter Server',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.pink,
      ),
      home: MyHomePage(title: 'Flutter Server App'),
    );
  


class MyHomePage extends StatefulWidget 
  MyHomePage(Key key, this.title) : super(key: key);
  final String title;

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


class _MyHomePageState extends State<MyHomePage> 
  Future getData() async 
    var url = 'https://milk-white-reveille.000webhostapp.com/get.php';
    http.Response response = await http.get(url);
    var data = jsonDecode(response.body);
    return data;
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        centerTitle: true,
      ),
      body: FutureBuilder(
        future: getData(),
        builder: (BuildContext context, AsyncSnapshot snapshot) 
          if (snapshot.hasData)
            return ListView(
              children: snapshot.data.map((document) 
                return ListTile(
                  title: Text(document['title']),
                  subtitle: Text(document['type']),
                );
              ).toList(),
            );
          return Text('Loading...');
        ,
      ),
    );
  

【讨论】:

以上是关于从 mysql 获取数据到 StreamBuilder Flutter的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Mysql 数据库中获取数据到 Snowflake

使用php从mysql获取数据到android

从 mysql 获取数据到 StreamBuilder Flutter

使用 Sequelize 从 MySQL 获取数据到 GraphQL 失败

从 MySQL 数据库获取数据到 html 下拉列表

如何从 mysql 获取数据到 ckeditor textarea?