异常:Context是null,请先调用ToastContext.init(Context)



问题出现在Toast上。dart和Armodel.dart。如果可能的话,请告诉我如何实现OCR,因为我跟踪了Pubdev的代码,但仍然每当我打开我的相机它崩溃。

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class ToastContext {
BuildContext? context;
MethodChannel? _channel;
static final ToastContext _instance = ToastContext._internal();
/// Prmary Constructor for FToast
factory ToastContext() {
return _instance;
}
/// Take users Context and saves to avariable
ToastContext init(BuildContext context) {
_instance.context = context;
return _instance;
}
ToastContext._internal();
}
class Toast {
static const int lengthShort = 1;
static const int lengthLong = 3;
static const int bottom = 0;
static const int center = 1;
static const int top = 2;
static void show(String msg,
{int? duration = 1,
int? gravity = 0,
Color backgroundColor = const Color(0xAA000000),
textStyle = const TextStyle(fontSize: 15, color: Colors.white),
double backgroundRadius = 20,
bool? rootNavigator,
Border? border,
bool webShowClose = false,
Color webTexColor = const Color(0xFFffffff)}) {
if (ToastContext().context == null) {
throw Exception('Context is null, please call ToastContext.init(context) first');
}
if (kIsWeb == true) {
if (ToastContext()._channel == null) {
ToastContext()._channel = const MethodChannel('appdev/FlutterToast');
}
String toastGravity = "bottom";
if (gravity == Toast.top) {
toastGravity = "top";
} else if (gravity == Toast.center) {
toastGravity = "center";
} else {
toastGravity = "bottom";
}
final Map<String, dynamic> params = <String, dynamic>{
'msg': msg,
'duration': (duration ?? 1) * 1000,
'gravity': toastGravity,
'bgcolor': backgroundColor.toString(),
'textcolor': webTexColor.value.toRadixString(16),
'webShowClose': webShowClose,
};
ToastContext()._channel?.invokeMethod("showToast", params);
} else {
ToastView.dismiss();
ToastView.createView(msg, ToastContext().context!, duration, gravity, backgroundColor,
textStyle, backgroundRadius, border, rootNavigator);
}
}
}
class ToastView {
static final ToastView _singleton = ToastView._internal();
factory ToastView() {
return _singleton;
}
ToastView._internal();
static OverlayState? overlayState;
static OverlayEntry? _overlayEntry;
static bool _isVisible = false;
static void createView(
String msg,
BuildContext context,
int? duration,
int? gravity,
Color background,
TextStyle textStyle,
double backgroundRadius,
Border? border,
bool? rootNavigator) async {
overlayState = Overlay.of(context, rootOverlay: rootNavigator ?? false);
_overlayEntry = OverlayEntry(
builder: (BuildContext context) => ToastWidget(
widget: SizedBox(
width: MediaQuery.of(context).size.width,
child: Container(
alignment: Alignment.center,
width: MediaQuery.of(context).size.width,
child: Container(
decoration: BoxDecoration(
color: background,
borderRadius: BorderRadius.circular(backgroundRadius),
border: border,
),
margin: const EdgeInsets.symmetric(horizontal: 20),
padding: const EdgeInsets.fromLTRB(16, 10, 16, 10),
child: Text(msg, softWrap: true, style: textStyle),
)),
),
gravity: gravity),
);
_isVisible = true;
overlayState!.insert(_overlayEntry!);
await Future.delayed(Duration(seconds: duration ?? Toast.lengthShort));
dismiss();
}
static dismiss() async {
if (!_isVisible) {
return;
}
_isVisible = false;
_overlayEntry?.remove();
}
}
class ToastWidget extends StatelessWidget {
const ToastWidget({
Key? key,
required this.widget,
required this.gravity,
}) : super(key: key);
final Widget widget;
final int? gravity;
@override
Widget build(BuildContext context) {
return Positioned(
top: gravity == 2 ? MediaQuery.of(context).viewInsets.top + 50 : null,
bottom: gravity == 0 ? MediaQuery.of(context).viewInsets.bottom + 50 : null,
child: IgnorePointer(
child: Material(
color: Colors.transparent,
child: widget,
),
));
}
}
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_mobile_vision_2/flutter_mobile_vision_2.dart';
import 'package:toast/toast.dart';
import 'arviewpage.dart';
class Armodelselect extends StatefulWidget {
@override
_ArmodelselectState createState() => _ArmodelselectState();
}
class _ArmodelselectState extends State<Armodelselect> {
int _cameraOcr = 0;
//String _textValue = "sample";
String position = "";
bool vision = false;
bool showwords = true;
bool search = false;
late String searchtext;
bool flash = false;
List<OcrText> scannedwords = [];
var DATA, DATA2, DATA3;
final databasepost = FirebaseDatabase.instance.reference();
final databasepost1 = FirebaseDatabase.instance.reference();
late OcrText selected;
@override
void initState() {
getdata();
FlutterMobileVision.start().then((x) => setState(() {
vision = true;
}));
super.initState();
}
Future<List<OcrText>> _getwords() async {
return scannedwords;
}
Future<bool> _onWillPop() async {
SystemNavigator.pop();
return false;
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: _onWillPop,
child: Container(
height: MediaQuery.of(context).size.height - 185.0,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(topLeft: Radius.circular(75.0)),
),
child: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
backgroundColor: Colors.transparent,
expandedHeight: 100,
floating: false,
pinned: false,
automaticallyImplyLeading: false,
flexibleSpace: FlexibleSpaceBar(
background:
Row(mainAxisAlignment: MainAxisAlignment.end, children: <
Widget>[
Padding(
padding: const EdgeInsets.all(10.0),
child: Container(
decoration: BoxDecoration(
color: Colors.grey[100],
border: Border.all(color: Colors.blue, width: 1.0),
borderRadius: BorderRadius.all(Radius.circular(5.0)),
boxShadow: [
BoxShadow(
blurRadius: 5,
color: Colors.black54,
offset: Offset(1, 3))
],
),
child: IconButton(
icon: Icon(
Icons.refresh,
color: Colors.blue[500],
),
onPressed: () {
setState(() {
getdata();
});
},
),
),
),
Visibility(
visible: !search,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Container(
decoration: BoxDecoration(
color: Colors.grey[100],
border: Border.all(color: Colors.blue, width: 1.0),
borderRadius:
BorderRadius.all(Radius.circular(5.0)),
boxShadow: [
BoxShadow(
blurRadius: 5,
color: Colors.black54,
offset: Offset(1, 3))
],
),
child: IconButton(
icon: Icon(
Icons.camera_alt,
color: Colors.blue[500],
),
onPressed: () {
camerarefresh();
},
),
),
),
),
Visibility(
visible: !search,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Container(
decoration: BoxDecoration(
color: Colors.grey[100],
border: Border.all(color: Colors.blue, width: 1.0),
borderRadius:
BorderRadius.all(Radius.circular(5.0)),
boxShadow: [
BoxShadow(
blurRadius: 5,
color: Colors.black54,
offset: Offset(1, 3))
],
),
child: IconButton(
icon:
Icon(flash ? Icons.flash_on : Icons.flash_off),
color: Colors.blue,
onPressed: () {
setState(() {
if (flash) {
flash = false;
} else {
flash = true;
}
});
},
),
),
),
),
Visibility(
visible: !search,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Container(
decoration: BoxDecoration(
color: Colors.grey[100],
border: Border.all(color: Colors.blue, width: 1.0),
borderRadius:
BorderRadius.all(Radius.circular(5.0)),
boxShadow: [
BoxShadow(
blurRadius: 5,
color: Colors.black54,
offset: Offset(1, 3))
],
),
child: IconButton(
icon: Icon(
Icons.list,
color: Colors.blue[500],
),
onPressed: () {
setState(() {
if (showwords) {
showwords = false;
} else {
showwords = true;
}
});
},
),
),
),
),
Padding(
padding: const EdgeInsets.all(10.0),
child: Container(
decoration: BoxDecoration(
color: Colors.grey[100],
border: Border.all(color: Colors.blue, width: 1.0),
borderRadius: BorderRadius.all(Radius.circular(5.0)),
boxShadow: [
BoxShadow(
blurRadius: 5,
color: Colors.black54,
offset: Offset(1, 3))
],
),
child: IconButton(
icon: Icon(
Icons.search,
color: Colors.blue[500],
),
onPressed: () {
setState(() {
if (search) {
search = false;
} else {
search = true;
}
});
},
),
),
),
Visibility(
visible: search,
child: Expanded(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: TextField(
decoration: InputDecoration(
labelText: "Keyword",
border: OutlineInputBorder()),
onChanged: (text) {
setState(() {
searchtext = text;
});
}),
),
),
),
]),
),
)
];
},
body: Container(
padding: EdgeInsets.fromLTRB(50, 10, 0, 0),
child: FutureBuilder(
future: _getwords(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (search) {
return Center(
child: RaisedButton(
color: Color(0xFF21BFBD),
onPressed: () {
searchbutton(searchtext);
},
child: Text("Build Model"),
),
);
} else if (scannedwords.length == 0 || !showwords) {
return Container();
} else if (scannedwords.length == 1) {
wordselected(scannedwords[0]);
return Container();
} else {
return Container(
child: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: scannedwords.length,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: GestureDetector(
onTap: () {
wordselected(scannedwords[index]);
},
child: Container(
decoration: BoxDecoration(
color: Colors.grey[100],
border: Border.all(
color: Colors.blue, width: 2.0),
borderRadius:
BorderRadius.all(Radius.circular(5.0)),
boxShadow: [
BoxShadow(
blurRadius: 5,
color: Colors.black54,
offset: Offset(1, 3))
],
),
padding: EdgeInsets.all(10),
child: Center(
child: Text(
processword(
scannedwords[index].value.toString(),
),
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w400,
fontSize: 30,
),
),
),
),
),
);
}),
);
}
}),
),
),
),
);
}
//functions:::::::::::::::
Future<void> camerarefresh() async {
_read();
}
//read live words from camera
_read() async {
try {
print(" $_cameraOcr");
scannedwords = await FlutterMobileVision.read(
camera: 0,
flash: flash,
waitTap: true,
autoFocus: true,
multiple: true,
showText: true,
fps: 30,
);
Future.delayed(Duration(seconds: 1), () {
setState(() {});
});
} catch (e) {
showToast("failed to recognize text");
}
}
//method when ocr word list is shown
Future<void> wordselected(OcrText word) async {
String name = word.value.toString().toLowerCase();
if (!checkname(name, DATA2['available'])) {
showToast("Ar data not available check after sometime");
changerequestword(name, DATA2['requested']);
} else {
print("${DATA[name]['image']}");
objmodel modeldes = new objmodel(
name,
DATA[name]['size'].toString().split(","),
DATA[name]['image'],
DATA[name]['explain'],
DATA[name]['type']);
Future.delayed(Duration(seconds: 2), () {
vision = false;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => arviewpage(modeldes),
),
);
});
}
}
//for search keyword button method implementation
Future<void> searchbutton(String word) async {
String name = word.toLowerCase();
print(DATA[0]);
if (!checkname(name, DATA2['available'])) {
showToast("Ar data not available check after sometime");
changerequestword(name, DATA2['requested']);
} else {
print("image${DATA[name]['image']}");
objmodel modeldes = new objmodel(
name,
DATA[name]['size'].toString().split(","),
DATA[name]['image'],
DATA[name]['explain'],
DATA[name]['type']);
Future.delayed(Duration(seconds: 2), () {
vision = false;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => arviewpage(modeldes),
),
);
});
}
}
//check if the word exist in the available,requested word list
bool checkname(String word, String list) {
var listc = list.split(",");
for (int i = 0; i < listc.length; i++) {
if (listc[i] == word) {
return true;
}
}
return false;
}
//make wordfrequency change request to firebase database
changerequestword(String word, String list) {
if (checkname(word, list)) {
int count = int.parse(DATA3[word]);
count = count + 1;
databasepost.child("wordfrequency").update({
"$word": "$count",
});
} else {
databasepost.child("wordfrequency").update({
"$word": "1",
});
if (list == "") {
databasepost1.child("wordlist").update({
"requested": "${word}",
});
} else {
databasepost1.child("wordlist").update({
"requested": "${list},${word}",
});
}
}
}
String processword(String word) {
String postword = "";
word.runes.forEach((int rune) {
var character = new String.fromCharCode(rune);
if (character == " ") {
postword = postword + " ";
} else {
postword = postword + character;
}
});
var w = postword.split("n");
postword = "";
for (int i = 0; i < w.length; i++) {
postword = postword + w[i] + " ";
}
return postword.trim();
}
//toast method
void showToast(String text) {
Toast.show(text,
textStyle: context, duration: Toast.lengthLong, gravity: Toast.bottom);
}
//get url for image from database
Future<void> getdata() async {
final reference =
await FirebaseDatabase.instance.reference().child("datamodel");
reference.once().then((DatabaseEvent snap) {
DATA = snap.snapshot;
});
final reference2 =
await FirebaseDatabase.instance.reference().child("wordlist");
reference2.once().then((DatabaseEvent snap) {
DATA2 = snap.snapshot;
});
final reference3 =
await FirebaseDatabase.instance.reference().child("wordfrequency");
reference3.once().then((DatabaseEvent snap) {
DATA3 = snap.snapshot;
});
}
}
class objmodel {
var size;
String name, img_url, type, explain;
objmodel(this.name, this.size, this.img_url, this.explain, this.type);
}
E/flutter ( 6018): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: Exception: Context is null, please call ToastContext.init(context) first
E/flutter ( 6018): #0      Toast.show (package:toast/toast.dart:42:7)
E/flutter ( 6018): #1      _ArmodelselectState.showToast (package:flutter_auth_ui/screens/armodelselect.dart:456:11)
E/flutter ( 6018): #2      _ArmodelselectState._read (package:flutter_auth_ui/screens/armodelselect.dart:344:7)
E

我认为你应该在主函数中调用这段代码。

void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
ToastContext().init(context);//-> This part
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}

因为在您的Toast类中,您有:

if (ToastContext().context == null) {
throw Exception('Context is null, please call ToastContext.init(context) first');
}

所以很明显,如果你的context是空的,将会抛出一个异常。在你发布的代码中,没有调用任何.init(...)方法来设置ToastContext类的上下文?

无论在何处初始化页面,都必须调用ToastContext类的init方法。最好在initState中调用它,或者在BUT在使用之前!

最新更新