将元素调用到文本小部件

Calling an element to a Text widget

我正在尝试从对象列表构建卡片小部件。我在最底部的最后一个文本(grabItem.title)returns错误:不是常量表达式

import 'package:flutter/material.dart';

//ItemData used in addnew.dart
class ItemData {
  final String id;
  final String score;
  final String title;
  final String description;

  ItemData({
    required this.id,
    required this.score,
    required this.title,
    required this.description});

//@override
//String toString() => '{ID: $id, Score: $score, Title: $title, Description: $description}';
}

//Dummy list of items
final itemList = [
  ItemData(
      id: 'one',
      score: '30',
      title: 'Title One',
      description: 'mock description'),
  ItemData(
      id: 'two',
      score: '10',
      title: 'Title Two',
      description: 'mock description'),
  ItemData(
      id: 'three',
      score: '20',
      title: 'Title Three',
      description: 'mock description'),
];



class ListPage extends StatelessWidget {
  const ListPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return  Scaffold(
      appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text('List View',
          style: TextStyle(
            letterSpacing: 2.0,
          ),
        ),
        centerTitle: true,
      ),
      body: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
           Center(
             child: Listcard(),
           ),
          ], //childern
      ),
    );
  }
}

sortList(){
  //itemList.sort((item1, item2)=> item2.score.compareTo(item1.score));
}

class Listcard extends StatefulWidget {
  const Listcard({Key? key}) : super(key: key);

  @override
  _ListcardState createState() => _ListcardState();
}

class _ListcardState extends State<Listcard> {
  @override
  Widget build(BuildContext context) {

    sortList();
    var grabItem = itemList[0]; //grab the given instance to use as a list of elements
print(grabItem.title);

    return
      Card(
        child: InkWell(
          splashColor: Colors.blue.withAlpha(30),
          onLongPress: (){
            //print(cardTitle);
          },
          child: const SizedBox(
            width: 300,
            height: 100,
            child: Text(grabItem.title),
          ),

        ),
      );
  }
}

最终我想为每张卡片创建一个实例(针对每个列表对象),这样我就可以在脚手架上看到我的所有项目。我对 OOP 很陌生,所以我可能会以一种非常低效的方式来处理这个问题。

简短修复

只需删除 SizedBox 之前的 const:

class _ListcardState extends State<Listcard> {
  @override
  Widget build(BuildContext context) {

    sortList();
    var grabItem = itemList[0]; //grab the given instance to use as a list of elements
print(grabItem.title);

    return
      Card(
        child: InkWell(
          splashColor: Colors.blue.withAlpha(30),
          onLongPress: (){
            //print(cardTitle);
          },
          child:  SizedBox(
            width: 300,
            height: 100,
            child: Text(grabItem.title),
          ),

        ),
      );
  }
}

为什么? 因为将 SizedBox 标记为编译时间 constant 也会使文本成为编译时间常量,而事实并非如此。

完整的解决方案

按照您的意愿删除 SizedBox 之前的常量后,您可以使用 ListView 来显示元素 Listcard :

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: const ListPage(),
    );
  }
}

//ItemData used in addnew.dart
class ItemData {
  final String id;
  final String score;
  final String title;
  final String description;

  ItemData({required this.id, required this.score, required this.title, required this.description});

//@override
//String toString() => '{ID: $id, Score: $score, Title: $title, Description: $description}';
}

//Dummy list of items
final itemList = [
  ItemData(id: 'one', score: '30', title: 'Title One', description: 'mock description'),
  ItemData(id: 'two', score: '10', title: 'Title Two', description: 'mock description'),
  ItemData(id: 'three', score: '20', title: 'Title Three', description: 'mock description'),
];

class ListPage extends StatefulWidget {
  const ListPage({Key? key}) : super(key: key);

  @override
  State<ListPage> createState() => _ListPageState();
}

class _ListPageState extends State<ListPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text(
          'List View',
          style: TextStyle(
            letterSpacing: 2.0,
          ),
        ),
        centerTitle: true,
      ),
// By using a listView we lazily populate the items and pass to the `ListCard` the single item it needs
      body: ListView.builder(
          itemCount: itemList.length,
          itemBuilder: (context, index) {
            return ListCard(item: itemList[index]);
          }),
    );
  }

  @override
  void initState() {
    super.initState();

    sortList(); //perform computations off the build method of the widgets move it to the lifecycle methods of StatefulWidgets or to a State management solution.
  }
}

sortList() {
  itemList.sort((item1, item2) => item2.score.compareTo(item1.score));
}

class ListCard extends StatelessWidget {
  final ItemData item;
  const ListCard({Key? key, required this.item}) : super(key: key);

  @override
  Widget build(BuildContext context) {
//You should not perform side effects inside the build method of widgets
    return Card(
      child: InkWell(
        splashColor: Colors.blue.withAlpha(30),
        onLongPress: () {
          //print(cardTitle);
        },
        child: SizedBox(
          width: 300,
          height: 100,
          child: Text(item.title),
        ),
      ),
    );
  }
}

最后你应该看到这样的东西: