how to use bar code to extract information from an api and parse it to a user details widget screen - in flutter

杀马特。学长 韩版系。学妹 提交于 2020-08-10 19:22:11

问题


I am trying to use bar code to extract information of the user for example user's picture, display name and blah blah... pass all those data to for example userDetails widget page. so, after the barcode is scanned and data is extracted.it should navigate using the Navigator class. without this api I scan anything and parse it to the details page but when I tried to do the real thing its not working saying string cannot be assigned to a parameter type. please can somebody help i have been trying it for 3 days now. this is the base url: https://jsonplaceholder.typicode.com/Albums I am trying to use this for demo purpose. And this is the the url I have encoded into https://jsonplaceholder.typicode.com/Albums/1.

Barcode page:


import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:barcode_scan/barcode_scan.dart';
import 'package:erg_app/api/albumservice.dart';
import 'package:erg_app/AlbumDetails.dart';
import 'package:erg_app/models/album_model.dart';
void main() => runApp(MaterialApp(
      debugShowCheckedModeBanner: false,
      home: ScanPage(),
    ));

class ScanPage extends StatefulWidget {
  @override
  ScanPageState createState() {
      return new ScanPageState();
  }
}

class ScanPageState extends State<ScanPage> {
  String album = '';
  final HttpService httpService = HttpService();


  Future _scanQR() async {
    try {
      String qrResult = await BarcodeScanner.scan();
      
      
      return Scaffold(
         body:  FutureBuilder(
          future: httpService.getAlbums(),
          builder: (BuildContext context, AsyncSnapshot<List<Album>> snapshot) {
            if (snapshot.hasData) {
              List<Album> albums = snapshot.data;
               albums.map(
                      (Album album) => 
                        Navigator.of(context).push(
                          MaterialPageRoute(
                            builder: (context) => AlbumDetailsPage(
                               album : qrResult, // this is the issue
                            ),
                          ),
                        ),
                      
                    );  
            } else {
              return Center(child: CircularProgressIndicator());
            }
          },
        ),
      );
      
    } on PlatformException catch (ex) {
      if (ex.code == BarcodeScanner.CameraAccessDenied) {
        setState(() {
          album = "Camera permission was denied";
        });
      } else {
        setState(() {
          album = "Unknown Error $ex";
        });
      }
    } on FormatException {
      setState(() {
        album = "You pressed the back button before scanning anything";
      });
    } catch (ex) {
      setState(() {
        album = "Unknown Error $ex";
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('View Album Details'),
        iconTheme: IconThemeData(color: Colors.white),
        backgroundColor: Colors.green,
      ),
     
        // body: Center(
        //   child: Text(
        //     result,
        //     style: new TextStyle(fontSize: 30.0, fontWeight: FontWeight.bold),
        //   ),
          
        // ),

      floatingActionButton: FloatingActionButton.extended(
            icon: Icon(Icons.camera_alt),
            label: Text("Scan Album"),
            onPressed: _scanQR,
          ),
          floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
        );

    
  }
}


Details Page:

import 'package:erg_app/StartScan.dart';
import 'package:flutter/material.dart';
import 'package:erg_app/models/album_model.dart';

// void main() {
//   runApp(ProfilePage());
// }
  

class AlbumDetailsPage extends StatelessWidget {
  
 
  final Album album;
  AlbumDetailsPage({@required this.album});
  
  
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
       debugShowCheckedModeBanner: false,

      home: Scaffold(
         appBar: AppBar(

          title: new Center(child: new Text('Album Details:', textAlign: TextAlign.left)),
          iconTheme: IconThemeData(color: Colors.white),
          backgroundColor: Colors.green, 
          leading: new IconButton(
          icon: new Icon(Icons.assignment_ind),
          onPressed: () {},
        ),
        
        ),
        // backgroundColor: Colors.green[50],
        body: Container(
          child: ListView(
            
              children: <Widget>[
                Container(margin: EdgeInsets.only(top: 20),),
                CircleAvatar(
                  radius: 80,
                  backgroundColor: Colors.grey,
                    // backgroundImage: AssetImage('assets/images/user.png'),
                  
                ),
                Text(
                  album.title,
                  style: TextStyle(
                    fontFamily: 'SourceSansPro',
                    fontSize: 25,
                  ),
                  textAlign: TextAlign.center,

                ),
                Text(
                  'Welcome',
                  style: TextStyle(
                    fontSize: 20,
                    fontFamily: 'SourceSansPro',
                    color: Colors.green[400],
                    letterSpacing: 2.5,
                  ),
                 textAlign: TextAlign.center,
                ),
                Container(margin: EdgeInsets.only(top: 20),),
                SizedBox(
                  height: 20.0,
                  width: 200,
                  child: Divider(
                    color: Colors.teal[100],
                  ),
                ),
                Text(
                  'Album Details',
                  textAlign: TextAlign.center,

                
                ),
                
                Card(
                      color: Colors.white,
                      margin:
                          EdgeInsets.symmetric(vertical: 10.0, horizontal: 25.0),
                      child: ListTile(
                        leading: Text(
                            'ID:',
                            style: TextStyle(
                              fontSize: 20,
                              fontFamily: 'SourceSansPro',
                              color: Colors.green[700],
                              letterSpacing: 2.5,
                          ),
                        ),
                        title: Text("${album.userId}",
                          // result,
                          style:
                              TextStyle(fontFamily: 'BalooBhai', fontSize: 20.0),
                        ), 
                      ), 
                    ),
                
                Card(
                      color: Colors.white,
                      margin:
                          EdgeInsets.symmetric(vertical: 10.0, horizontal: 25.0),
                      child: ListTile(
                        leading: Text(
                            'Title:',
                            style: TextStyle(
                              fontSize: 20,
                              fontFamily: 'SourceSansPro',
                              color: Colors.green[700],
                              letterSpacing: 2.5,
                          ),
                        ),
                        title: Text(
                          album.title,
                          style:
                              TextStyle(fontFamily: 'BalooBhai', fontSize: 20.0),
                        ), 
                      ), 
                    ),

                    
                    Card(
                      color: Colors.white,
                      margin:
                          EdgeInsets.symmetric(vertical: 10.0, horizontal: 25.0),
                      child: ListTile(
                        leading: Text(
                            'Body:',
                            style: TextStyle(
                              fontSize: 20,
                              fontFamily: 'SourceSansPro',
                              color: Colors.green[700],
                              letterSpacing: 2.5,
                          ),
                        ),
                        title: Text(
                          album.body,
                          style:
                              TextStyle(fontFamily: 'BalooBhai', fontSize: 20.0),
                        ), 
                      ), 
                    ),

                    Container(
                      margin: EdgeInsets.only(top: 20, bottom: 30),
                      child: Center(
                        child: RaisedButton(
                          padding: EdgeInsets.fromLTRB(80, 10, 80, 10),
                          color: Colors.green,
                          child: Text("Close", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 14), ),
                          onPressed: () {
                            Navigator.of(context).push(MaterialPageRoute(builder: (context) =>StartScanPage()));
                          },
                          shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(50),
                        ),
                        ),
                      ),
                  ),
              ],
          ),
        ),
      ),
    );
  }
}

the Model:


import 'dart:convert';

Album albumFromJson(String str) => Album.fromJson(json.decode(str));

String albumToJson(Album data) => json.encode(data.toJson());

class Album {
    Album({
        this.userId,
        this.id,
        this.title,
        this.body,
    });

    int userId;
    int id;
    String title;
    String body;

    factory Album.fromJson(Map<String, dynamic> json) => Album(
        userId: json["userId"],
        id: json["id"],
        title: json["title"],
        body: json["body"],
    );

    Map<String, dynamic> toJson() => {
        "userId": userId,
        "id": id,
        "title": title,
        "body": body,
    };
}

The ApiServiceFile:

import 'dart:convert';
import 'package:http/http.dart';
import 'package:erg_app/models/album_model.dart';

class HttpService {
  final String postsURL = "https://jsonplaceholder.typicode.com/Albums";

  Future<List<Album>> getAlbums() async {
    Response res = await get(postsURL);

    if (res.statusCode == 200) {
      List<dynamic> body = jsonDecode(res.body);

      List<Album> Albums = body
          .map(
            (dynamic item) => Album.fromJson(item),
          )
          .toList();

      return Albums;
    } else {
      throw "Can't get Albums.";
    }
  }
}

回答1:


You can copy paste run full code below
Assume barcode scan result return "1", I use the following code snippet to simulate

Future<ScanResult> simulateBarcodeScan() {
  Future.delayed(Duration(seconds: 3), () {});
  return Future.value(ScanResult(rawContent: "1"));
}

Step 1: You can not put FutureBuilder in _scanQR()
Step 2: _scanQR() code snippet

Future<Album> _scanQR() async {
    try {
      //ScanResult qrResult = await BarcodeScanner.scan();
      ScanResult qrResult = await simulateBarcodeScan();
      print(qrResult.rawContent);
      _future = httpService.getAlbums(qrResult.rawContent);
      setState(() {});

Step 3: You can use addPostFrameCallback to do Navigate

  Album album = snapshot.data;
  print(album.toString());
  WidgetsBinding.instance.addPostFrameCallback((_) {
    Navigator.of(context).push(
      MaterialPageRoute(
        builder: (context) =>
            AlbumDetailsPage(album: album // this is the issue
                ),
      ),
    );
  });
  return Container();

working demo

full code

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

class HttpService {
  final String postsURL = "https://jsonplaceholder.typicode.com/Albums";

  Future<Album> getAlbums(String rawContent) async {
    String url = postsURL + "/$rawContent";
    print(url);
    Response res = await get(url);

    print(res.toString());
    if (res.statusCode == 200) {
      print("in");
      return albumFromJson(res.body);
    } else {
      throw "Can't get Albums.";
    }
  }
}

Album albumFromJson(String str) => Album.fromJson(json.decode(str));

String albumToJson(Album data) => json.encode(data.toJson());

class Album {
  Album({
    this.userId,
    this.id,
    this.title,
    this.body,
  });

  int userId;
  int id;
  String title;
  String body;

  factory Album.fromJson(Map<String, dynamic> json) => Album(
        userId: json["userId"],
        id: json["id"],
        title: json["title"],
        body: json["body"],
      );

  Map<String, dynamic> toJson() => {
        "userId": userId,
        "id": id,
        "title": title,
        "body": body,
      };
}

class ScanPage extends StatefulWidget {
  @override
  ScanPageState createState() {
    return new ScanPageState();
  }
}

Future<ScanResult> simulateBarcodeScan() {
  Future.delayed(Duration(seconds: 3), () {});
  return Future.value(ScanResult(rawContent: "1"));
}

class ScanPageState extends State<ScanPage> {
  String album = '';
  final HttpService httpService = HttpService();

  Future<Album> _scanQR() async {
    try {
      //ScanResult qrResult = await BarcodeScanner.scan();
      ScanResult qrResult = await simulateBarcodeScan();
      print(qrResult.rawContent);
      _future = httpService.getAlbums(qrResult.rawContent);
      setState(() {});
    } on PlatformException catch (ex) {
      /*if (ex.code == BarcodeScanner.CameraAccessDenied) {
        setState(() {
          album = "Camera permission was denied";
        });
      } else {
        setState(() {
          album = "Unknown Error $ex";
        });
      }*/
    } on FormatException {
     /* setState(() {
        album = "You pressed the back button before scanning anything";
      });*/
    } catch (ex) {
     /* setState(() {
        album = "Unknown Error $ex";
      });*/
    }
  }

  Future<Album> _future;
  @override
  void initState() {
    // TODO: implement initState
    _future = null;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('View Album Details'),
        iconTheme: IconThemeData(color: Colors.white),
        backgroundColor: Colors.green,
      ),
      body: FutureBuilder(
          future: _future,
          builder: (BuildContext context, AsyncSnapshot<Album> snapshot) {
            print(snapshot.connectionState);
            switch (snapshot.connectionState) {
              case ConnectionState.none:
                return Container();
              case ConnectionState.waiting:
                return Center(child: CircularProgressIndicator());
              case ConnectionState.active:
                return Text('');
              case ConnectionState.done:
                if (snapshot.hasError) {
                  return Text(
                    '${snapshot.error}',
                    style: TextStyle(color: Colors.red),
                  );
                } else {
                  print("hasdata");
                  Album album = snapshot.data;
                  print(album.toString());
                  WidgetsBinding.instance.addPostFrameCallback((_) {
                    Navigator.of(context).push(
                      MaterialPageRoute(
                        builder: (context) =>
                            AlbumDetailsPage(album: album // this is the issue
                                ),
                      ),
                    );
                  });
                  return Container();
                }
            }
          }),
      floatingActionButton: FloatingActionButton.extended(
        icon: Icon(Icons.camera_alt),
        label: Text("Scan Album"),
        onPressed: _scanQR,
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
    );
  }
}

class AlbumDetailsPage extends StatelessWidget {
  final Album album;
  AlbumDetailsPage({@required this.album});

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: new Center(
            child: new Text('Album Details:', textAlign: TextAlign.left)),
        iconTheme: IconThemeData(color: Colors.white),
        backgroundColor: Colors.green,
        leading: new IconButton(
          icon: new Icon(Icons.assignment_ind),
          onPressed: () {},
        ),
      ),
      // backgroundColor: Colors.green[50],
      body: Container(
        child: ListView(
          children: <Widget>[
            Container(
              margin: EdgeInsets.only(top: 20),
            ),
            CircleAvatar(
              radius: 80,
              backgroundColor: Colors.grey,
              // backgroundImage: AssetImage('assets/images/user.png'),
            ),
            Text(
              "${album.title}",
              style: TextStyle(
                fontFamily: 'SourceSansPro',
                fontSize: 25,
              ),
              textAlign: TextAlign.center,
            ),
            Text(
              'Welcome',
              style: TextStyle(
                fontSize: 20,
                fontFamily: 'SourceSansPro',
                color: Colors.green[400],
                letterSpacing: 2.5,
              ),
              textAlign: TextAlign.center,
            ),
            Container(
              margin: EdgeInsets.only(top: 20),
            ),
            SizedBox(
              height: 20.0,
              width: 200,
              child: Divider(
                color: Colors.teal[100],
              ),
            ),
            Text(
              'Album Details',
              textAlign: TextAlign.center,
            ),
            Card(
              color: Colors.white,
              margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 25.0),
              child: ListTile(
                leading: Text(
                  'ID:',
                  style: TextStyle(
                    fontSize: 20,
                    fontFamily: 'SourceSansPro',
                    color: Colors.green[700],
                    letterSpacing: 2.5,
                  ),
                ),
                title: Text(
                  "${album.userId}",
                  // result,
                  style: TextStyle(fontFamily: 'BalooBhai', fontSize: 20.0),
                ),
              ),
            ),
            Card(
              color: Colors.white,
              margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 25.0),
              child: ListTile(
                leading: Text(
                  'Title:',
                  style: TextStyle(
                    fontSize: 20,
                    fontFamily: 'SourceSansPro',
                    color: Colors.green[700],
                    letterSpacing: 2.5,
                  ),
                ),
                title: Text(
                  "${album.title}",
                  style: TextStyle(fontFamily: 'BalooBhai', fontSize: 20.0),
                ),
              ),
            ),
            Card(
              color: Colors.white,
              margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 25.0),
              child: ListTile(
                leading: Text(
                  'Body:',
                  style: TextStyle(
                    fontSize: 20,
                    fontFamily: 'SourceSansPro',
                    color: Colors.green[700],
                    letterSpacing: 2.5,
                  ),
                ),
                title: Text(
                  "${album.body}",
                  style: TextStyle(fontFamily: 'BalooBhai', fontSize: 20.0),
                ),
              ),
            ),
            Container(
              margin: EdgeInsets.only(top: 20, bottom: 30),
              child: Center(
                child: RaisedButton(
                  padding: EdgeInsets.fromLTRB(80, 10, 80, 10),
                  color: Colors.green,
                  child: Text(
                    "Close",
                    style: TextStyle(
                        color: Colors.white,
                        fontWeight: FontWeight.bold,
                        fontSize: 14),
                  ),
                  onPressed: () {
                    //Navigator.of(context).push(MaterialPageRoute(builder: (context) =>StartScanPage()));
                  },
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(50),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: ScanPage(),
    );
  }
}



回答2:


this is the exact issue :

  Future _scanQR() async {
    try {
      String qrResult = await BarcodeScanner.scan();
      
      
      return Scaffold(
         body:  FutureBuilder(
          future: httpService.getAlbums(),
          builder: (BuildContext context, AsyncSnapshot<List<Album>> snapshot) {
            if (snapshot.hasData) {
              List<Album> albums = snapshot.data;
               albums.map(
                      (Album album) => 
                        Navigator.of(context).push(
                          MaterialPageRoute(
                            builder: (context) => AlbumDetailsPage(
                               album : qrResult, // this is the issue
                            ),
                          ),
                        ),
                      
                    );  
            } else {
              return Center(child: CircularProgressIndicator());
            }
          },
        ),
      );
      
    }


来源:https://stackoverflow.com/questions/62518934/how-to-use-bar-code-to-extract-information-from-an-api-and-parse-it-to-a-user-de

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!