如何修复 Flutter NosuchmethodError?
Ho to fix Flutter NosuchmethodError?
我收到这个错误:
NosuchmethodError: Class 'List' 没有实例 setter 'state='。
接收方:“_GrowableList”的实例(长度:0) 尝试调用:“_GrowableList”的状态=实例(长度:15)
而且我不知道问题出在哪里我在代码中看不到任何问题。
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:quiz2/const/const.dart';
import 'package:sqflite/sqflite.dart';
class Category {
int ID;
String name, image;
Map<String, dynamic> toMap() {
var map = <String, dynamic> {
columnMainCategoryId: ID,
columnCategoryName: name,
columnCategoryImage: image
};
return map;
}
Category();
Category.fromMap(Map<String,dynamic> map) {
ID = map[columnMainCategoryId];
name = map[columnCategoryName];
image = map[columnCategoryImage];
}
}
class CategoryProvider {
Future<Category> getCategoryById(Database db, int id)async {
var maps = await db.query(tableCategoryName,
columns: [
columnMainCategoryId,
columnCategoryName,
columnCategoryImage
], where: "$columnMainCategoryId=?",
whereArgs: [id]);
if(maps.length > 0)
return Category.fromMap(maps.first);
return null;
}
Future<List<Category>> getCategories(Database db) async{
var maps = await db.query(tableCategoryName,
columns: [
columnMainCategoryId,
columnCategoryName,
columnCategoryImage
]);
if(maps.length > 0) return maps.map((category) => Category.fromMap(category)).toList();
return null;
}
}
class CategoryList extends StateNotifier<List<Category>>{
CategoryList(List<Category> state):super(state ?? []);
void addAll(List<Category> category)
{
state.addAll(category);
}
void add(Category category){
state = [
...state,
category,
];
}
}
文件const.dart
final db_name = "quiz.db";
final columnMainCategoryId = "ID";
final columnCategoryName = "Name";
final columnCategoryImage = "Image";
final tableCategoryName = "Category";
main.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:quiz2/screens/home_page.dart';
void main() {
runApp(ProviderScope(child:MyApp()));
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
routes: {
"/homePage": (context) => MyCategoryPage(title: "My Quiz",)
},
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Topics'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
Navigator.of(context).pop();
Navigator.pushNamed(context, "/homePage");
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
// This trailing comma makes auto-formatting nicer for build methods.
);
}
}
screens/home_page.飞镖
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:quiz2/const/state.dart';
import 'package:quiz2/database/category_provider.dart';
import 'package:quiz2/database/db_helper.dart';
class MyCategoryPage extends StatefulWidget {
MyCategoryPage({Key key, this.title}):super(key: key);
final String title;
@override
_MyCategoryPageState createState() => _MyCategoryPageState();
}
class _MyCategoryPageState extends State<MyCategoryPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder<List<Category>>(
future: getCategories(),
builder: (context, snapshot){
if(snapshot.hasError)
return Center(child: Text('${snapshot.error}'),);
else if(snapshot.hasData)
{
Category category = new Category();
category.ID = -1;
category.name = "Exam";
snapshot.data.add(category);
return GridView.count(
crossAxisCount: 2,
childAspectRatio: 1.0,
padding: const EdgeInsets.all(4.0),
mainAxisSpacing: 4.0,
crossAxisSpacing: 4.0,
children: snapshot.data.map((category){
return GestureDetector(child: Card(
elevation: 2,
color: category.ID == -1 ? Colors.green : Colors.white,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: AutoSizeText(
"${category.name}",
style: TextStyle(
color: category.ID == -1 ? Colors.white : Colors.black,
fontWeight: FontWeight.bold
),
maxLines: 1,
textAlign: TextAlign.center,
)
,)
],
),
),);
}).toList(),
);
}
else return Center(child: CircularProgressIndicator(),);
},
)
);
}
Future<List<Category>> getCategories() async {
var db = await copyDB();
var result = await CategoryProvider().getCategories(db);
context.read(categoryListProvider).state = result;
return result;
}
}
db_helper.dart
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:quiz2/const/const.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
Future<Database> copyDB() async{
var dbPath = await getDatabasesPath();
var path = join(dbPath, db_name);
var exists = await databaseExists(path);
if(!exists){
try{
await Directory(dirname(path)).create(recursive:true);
} catch(_){
}
ByteData data = await rootBundle.load(join("assets/db",db_name));
List<int> bytes = data.buffer.asUint8List(data.offsetInBytes,data.lengthInBytes);
await File(path).writeAsBytes(bytes, flush:true);
}else{
print("DB already exists!");
}
return await openDatabase(path, readOnly: true);
}
state.dart
import 'package:flutter_riverpod/all.dart';
import 'package:quiz2/database/category_provider.dart';
final categoryListProvider = StateNotifierProvider((ref) => new CategoryList([]));
NosuchmethodError: Class 'List' 没有实例 setter 'state='。
接收方:“_GrowableList”的实例(长度:0)
尝试调用:state=Instance(lenght:15) of '_GrowableList'
在您的代码中,您有
Future<List<Category>> getCategories() async {
var db = await copyDB();
var result = await CategoryProvider().getCategories(db);
context.read(categoryListProvider).state = result;
return result;
}
这里,你的context.read(categoryListProvider)
其实是List
类型的。
这就是为什么,当你这样称呼它时,就意味着你在呼唤,
[/* some kind of list */].state = result
但是,List
class 没有名为 state
的 属性,但您正在尝试修改它。这就是错误出现的原因。
注释掉该行并检查。
我收到这个错误:
NosuchmethodError: Class 'List' 没有实例 setter 'state='。 接收方:“_GrowableList”的实例(长度:0) 尝试调用:“_GrowableList”的状态=实例(长度:15)
而且我不知道问题出在哪里我在代码中看不到任何问题。
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:quiz2/const/const.dart';
import 'package:sqflite/sqflite.dart';
class Category {
int ID;
String name, image;
Map<String, dynamic> toMap() {
var map = <String, dynamic> {
columnMainCategoryId: ID,
columnCategoryName: name,
columnCategoryImage: image
};
return map;
}
Category();
Category.fromMap(Map<String,dynamic> map) {
ID = map[columnMainCategoryId];
name = map[columnCategoryName];
image = map[columnCategoryImage];
}
}
class CategoryProvider {
Future<Category> getCategoryById(Database db, int id)async {
var maps = await db.query(tableCategoryName,
columns: [
columnMainCategoryId,
columnCategoryName,
columnCategoryImage
], where: "$columnMainCategoryId=?",
whereArgs: [id]);
if(maps.length > 0)
return Category.fromMap(maps.first);
return null;
}
Future<List<Category>> getCategories(Database db) async{
var maps = await db.query(tableCategoryName,
columns: [
columnMainCategoryId,
columnCategoryName,
columnCategoryImage
]);
if(maps.length > 0) return maps.map((category) => Category.fromMap(category)).toList();
return null;
}
}
class CategoryList extends StateNotifier<List<Category>>{
CategoryList(List<Category> state):super(state ?? []);
void addAll(List<Category> category)
{
state.addAll(category);
}
void add(Category category){
state = [
...state,
category,
];
}
}
文件const.dart
final db_name = "quiz.db";
final columnMainCategoryId = "ID";
final columnCategoryName = "Name";
final columnCategoryImage = "Image";
final tableCategoryName = "Category";
main.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:quiz2/screens/home_page.dart';
void main() {
runApp(ProviderScope(child:MyApp()));
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
routes: {
"/homePage": (context) => MyCategoryPage(title: "My Quiz",)
},
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Topics'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
Navigator.of(context).pop();
Navigator.pushNamed(context, "/homePage");
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
// This trailing comma makes auto-formatting nicer for build methods.
);
}
}
screens/home_page.飞镖
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:quiz2/const/state.dart';
import 'package:quiz2/database/category_provider.dart';
import 'package:quiz2/database/db_helper.dart';
class MyCategoryPage extends StatefulWidget {
MyCategoryPage({Key key, this.title}):super(key: key);
final String title;
@override
_MyCategoryPageState createState() => _MyCategoryPageState();
}
class _MyCategoryPageState extends State<MyCategoryPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder<List<Category>>(
future: getCategories(),
builder: (context, snapshot){
if(snapshot.hasError)
return Center(child: Text('${snapshot.error}'),);
else if(snapshot.hasData)
{
Category category = new Category();
category.ID = -1;
category.name = "Exam";
snapshot.data.add(category);
return GridView.count(
crossAxisCount: 2,
childAspectRatio: 1.0,
padding: const EdgeInsets.all(4.0),
mainAxisSpacing: 4.0,
crossAxisSpacing: 4.0,
children: snapshot.data.map((category){
return GestureDetector(child: Card(
elevation: 2,
color: category.ID == -1 ? Colors.green : Colors.white,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: AutoSizeText(
"${category.name}",
style: TextStyle(
color: category.ID == -1 ? Colors.white : Colors.black,
fontWeight: FontWeight.bold
),
maxLines: 1,
textAlign: TextAlign.center,
)
,)
],
),
),);
}).toList(),
);
}
else return Center(child: CircularProgressIndicator(),);
},
)
);
}
Future<List<Category>> getCategories() async {
var db = await copyDB();
var result = await CategoryProvider().getCategories(db);
context.read(categoryListProvider).state = result;
return result;
}
}
db_helper.dart
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:quiz2/const/const.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
Future<Database> copyDB() async{
var dbPath = await getDatabasesPath();
var path = join(dbPath, db_name);
var exists = await databaseExists(path);
if(!exists){
try{
await Directory(dirname(path)).create(recursive:true);
} catch(_){
}
ByteData data = await rootBundle.load(join("assets/db",db_name));
List<int> bytes = data.buffer.asUint8List(data.offsetInBytes,data.lengthInBytes);
await File(path).writeAsBytes(bytes, flush:true);
}else{
print("DB already exists!");
}
return await openDatabase(path, readOnly: true);
}
state.dart
import 'package:flutter_riverpod/all.dart';
import 'package:quiz2/database/category_provider.dart';
final categoryListProvider = StateNotifierProvider((ref) => new CategoryList([]));
NosuchmethodError: Class 'List' 没有实例 setter 'state='。 接收方:“_GrowableList”的实例(长度:0) 尝试调用:state=Instance(lenght:15) of '_GrowableList'
在您的代码中,您有
Future<List<Category>> getCategories() async {
var db = await copyDB();
var result = await CategoryProvider().getCategories(db);
context.read(categoryListProvider).state = result;
return result;
}
这里,你的context.read(categoryListProvider)
其实是List
类型的。
这就是为什么,当你这样称呼它时,就意味着你在呼唤,
[/* some kind of list */].state = result
但是,List
class 没有名为 state
的 属性,但您正在尝试修改它。这就是错误出现的原因。
注释掉该行并检查。