【问题标题】:Return Type isn't a Widget: SetState Problem返回类型不是小部件:SetState 问题
【发布时间】:2019-10-28 04:32:01
【问题描述】:

我在更新主页时遇到问题: 我想在我的页面中包含一个带有 itemBuilder 的 StatelessWidget。 Widget 使用 Cards 构建一个 ListView。 LongPress 应该删除一张卡片并更新页面,但它没有更新。这不可能发生,因为它是一个无状态的 Widget。

我已经尝试将 StatlessWidget 变成 StatefullWidget,但是在 itemBuilder 中我收到一个错误,指出返回类型“ProductList(..)”不是小部件

List<String> artikelNamen = [];
List<int> barcodes = [];

class WiederaufnahmePage extends StatefulWidget {
  @override
  _WiederaufnahmePageState createState() => _WiederaufnahmePageState();
}

class ProductList extends StatelessWidget {
  final String artb;
  final int brcde;
  final int indx;

  ProductList(this.artb, this.brcde, this.indx);

  @override
  Widget build(BuildContext context) {
    return new Card(
        child: ListTile(
          title: Text(artb,
          style: TextStyle(fontWeight: FontWeight.w500, fontSize: 20)),
          subtitle: Text(brcde.toString()),
          leading: Icon(
            Icons.fastfood,
            color: Colors.blue[500],
          ),
          trailing: Icon(Icons.keyboard_arrow_right),
          onTap: () {
            Navigator.pushNamed(context, "/BarcodePage");
          },
          onLongPress: () {
            _showSnackBar(artb);
            artikelNamen.removeAt(indx);
            barcodes.removeAt(indx);
            //setState(() {}); //This isn't working bc StatelessWidget
         },
    ));
  }
}

class _WiederaufnahmePageState extends State<WiederaufnahmePage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
           child: Expanded(
              child: SizedBox(
                  height: 200.0,
                  child: new ListView.builder(
                    reverse: false,
                    itemBuilder: (_, int index) => ProductList(
                        artikelNamen[index], barcodes[index], index),
                    itemCount: artikelNamen.length,
                  )
              )),
          ))
  }   
}

我不知道如何解决这个问题。显示的代码是实际的工作代码,我想在 ListTile 上的每个 LongPress 之后实现整个页面都会更新,因此删除的 Tile 不再可见。

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    首先将变量代码移动到 StatefulWidget 的状态是一个很好的做法,在这种情况下,ArtikelNamen 和条形码不应被 ProductList 访问。

    之后,更改 StatelessWidget 以接收 onLongPress 的回调函数并将其分配给卡片。然后您可以将 onLongPress 函数移动到 StatefulWidget(调用 setState)并将其作为参数传递给无状态小部件。

    你可以试试这样的:

    import 'package:flutter/material.dart';
    
    class WiederaufnahmePage extends StatefulWidget {
      @override
      _WiederaufnahmePageState createState() => _WiederaufnahmePageState();
    }
    
    class _WiederaufnahmePageState extends State<WiederaufnahmePage> {
      List<String> artikelNamen = ['item 1', 'item 2', 'item 3'];
      List<int> barcodes = [0, 1, 2];
      @override
      Widget build(BuildContext context) {
        return Container(
          padding: EdgeInsets.all(8.0),
          child: ListView.builder(
            reverse: false,
            itemBuilder: (BuildContext context, int index) => ProductList(
                artikelNamen[index], barcodes[index], () => onLongPress(index)),
            itemCount: artikelNamen.length,
          ),
        );
      }
    
      void onLongPress(int indx) {
        //_showSnackBar(artb);
        setState(() {
          artikelNamen.removeAt(indx);
          barcodes.removeAt(indx);
        });
      }
    }
    
    class ProductList extends StatelessWidget {
      final String artb;
      final int brcde;
      final onLongPress;
    
      ProductList(this.artb, this.brcde, this.onLongPress);
    
      @override
      Widget build(BuildContext context) {
        return new Card(
            child: ListTile(
          title: Text(artb,
              style: TextStyle(fontWeight: FontWeight.w500, fontSize: 20)),
          subtitle: Text(brcde.toString()),
          leading: Icon(
            Icons.fastfood,
            color: Colors.blue[500],
          ),
          trailing: Icon(Icons.keyboard_arrow_right),
          onTap: () {
            Navigator.pushNamed(context, "/BarcodePage");
          },
          onLongPress: onLongPress,
        ));
      }
    }
    

    【讨论】:

    • 感谢您的回答!我真的不知道如何实现这个,你能这么好心,给我一个小例子吗?
    • @Leon_sooter 我用一个工作示例更新了答案。
    • 非常感谢您的努力!我稍后会试试这个。
    猜你喜欢
    • 2021-09-11
    • 2021-09-27
    • 1970-01-01
    • 1970-01-01
    • 2021-09-19
    • 1970-01-01
    • 2021-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多