I’m encountering an issue while working with my Flutter code. I’m trying to implement a ListView builder within a custom widget, but I’m getting an error message that says: ‘Expected a value of type ‘(Object) => Widget’, but got one of type ‘(String) => SizedBox’. Despite my attempts to adjust the function types, the error persists.
I’m encountering an issue in my Flutter application when using a ListView builder within a custom widget. The error message I’m receiving is: "Expected a value of type ‘(Object) => Widget’, but got one of type ‘(String) => SizedBox’." I’ve provided the code below to illustrate the problem. I’ve tried adjusting the types of functions, but the error persists. Could someone please help me understand and resolve this issue?
const ContentDesktopAdminView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final colors = context.colors;
return Scaffold(
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: max(560, 560),
width: 1000,
child: SingleChildScrollView(
child: Column(
children: [
AnyPage(
articles: [
Article(
lastModified: DateTime.now(),
name: 'Something',
),
],
),
],
),
),
),
],
),
),
);
}
}
class ListViewColumn<T> extends StatelessWidget {
const ListViewColumn({
required this.itemList,
Key? key,
}) : super(key: key);
final List<ListModel<T>> itemList;
@override
Widget build(BuildContext context) {
return Column(
children: [
Row(
children: [
...itemList.map(
(e) => Column(
children: [
if (e.columnHeaderCell != null)
e.columnHeaderCell!(e.columnName ?? '')
else
Text(e.columnName ?? ''),
SizedBox(
width: 100.pw,
height: 100.pw,
child: ListView.builder(
itemCount: e.list.length,
itemBuilder: (BuildContext context, int index) =>
e.cell(e.list[index]),
),
),
],
),
),
],
),
],
);
}
}
class ListModel<T> {
ListModel({
required this.list,
required this.cell,
this.columnName,
this.columnHeaderCell,
});
final String? columnName;
final List<T> list;
final Widget Function(T value) cell;
final Widget Function(String value)? columnHeaderCell;
}
class AnyPage extends StatelessWidget {
const AnyPage({required this.articles, Key? key}) : super(key: key);
final List<Article> articles;
@override
Widget build(BuildContext context) {
return ListViewColumn(
itemList: [
ListModel(
list: articles.map((e) => e.name).toList(),
columnName: 'Title',
cell: (value) => SizedBox(
height: 20,
width: 100,
child: Text(value),
),
),
ListModel(
list: articles.map((e) => e.lastModified).toList(),
columnName: 'Last modified',
cell: (value) => SizedBox(
height: 20,
width: 100,
child: Text(value.toIso8601String()),
),
),
],
);
}
}
class Article {
Article({
required this.lastModified,
required this.name,
});
final String name;
final DateTime lastModified;
}
2
Answers
Seems in the first place article is a class and you are trying to achieve a list view by hand. If you are trying to create a listview, use ListView.builder widget instead. You can check all types of listviews available here
Listview types
Assuming you can define a list of articles you may want to use something like this.
As you can see I’m accessing each of the items and passing the article down MyCustomArticleWidget which is a widget that takes an article as parameter. You can define the stateless widget like this
Stacktrace:
the generic type of the two
ListModel
widgets in theitemList
are different (one beingString
and the other isDateTime
), hence the generic type ofListViewColumn
will beObject
which in its turn will enforce it’s childitemList
to beList<ListModel<Object>>
and thecell
function will beWidget Function(Object value) cell
and that’s the problem, since you can’t bind a WidgetFunction(<String> or <DateTime>)
to aWidget Function(Object)
easy solution:
just remove all generic types (aka
<T>
), and useWidget Function(dynamic value) cell
hard solution (but recommended):
refactor you code so that
itemList
wont take different generic type, since that is the root of the problem