Reputation: 650
I am a new Flutter learner and try some code snippets on dartpad.dev
to work around and see how do they work. This is a code I recently wrote but I don't know why it doesn't work?
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
Map<String, Object> x = {};
x.putIfAbsent('Jack', () => Person(name: "Jack", age: 10));
x.putIfAbsent('Joe', () => Person(name: "Joe", age: 10));
return Container(
child: ListView.builder(
itemBuilder: (context, index) => Person(
x.values.toList()[index].name, x.values.toList()[index].age),
itemCount: x.length),
);
}
}
class Person {
String? name;
int? age;
Person({
this.name,
this.age,
});
}
This is the Error I see on dartpad.dev
:
The return type 'Person' isn't a 'Widget', as required by the closure's context.
Upvotes: 1
Views: 3512
Reputation: 4577
you have to understand the way flutter works which is based around Widgets. Widgets are component that are put in a tree like structure in a logic of parent and children.
Person is a simple class you have created with two fields but it is not a Widget that can be used in the UI.
The UI tree you are building include a ListWidget that want to build a list of Widgets.
The builder hence expect a Widget, not a Person. You can use the Person to build the Widget though or transform your Person class into a stateless Widget.
I suggest you start reading here: https://docs.flutter.dev/development/ui/widgets-intro
To make your code works with a minimum adjustment you can try using a Text Widget in which you pass your Person details:
return Container(
child: ListView.builder(
itemBuilder: (context, index) => Text(
'${x.values.toList()[index].name}, ${x.values.toList()[index].age}'),
itemCount: x.length),
If instead you Transform Person into a Widget you have to make person extends a StelessWidget as follow. This way your Person class will have a build method that describe as that Widget should be built into the UI. The result will be the same.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
Map<String, Object> x = {};
x.putIfAbsent('Jack', () => Person(name: "Jack", age: 10));
x.putIfAbsent('Joe', () => Person(name: "Joe", age: 10));
return Container(
child: ListView.builder(
itemBuilder: (context, index) => x.values.toList()[index],
itemCount: x.length),
);
}
}
class Person extends StatelessWidget {
String? name;
int? age;
Person({
this.name,
this.age,
});
@override
Widget build(BuildContext context) {
return Text('$name, $age');
}
}
Upvotes: 1