繁体   English   中英

ListView 中的有状态小部件未更新

[英]Stateful Widget in a ListView is not getting updated

我有所有交易的列表_deals和选定交易的列表_selectedDeals 交易可以添加到另一个 class 的_selectedDeals列表中或从列表中删除。因此,如果添加/删除新交易,我想重建此DealsWidget ,以便新添加/删除的交易正确反映在 UI 中。

我正在使用BookButton有状态小部件,以显示是否选择了交易。 isBooked为真时,表示已选择交易。

我计划通过在从另一个 class 添加/删除数据后调用DealsWidgetrefresh() function 来实现此行为,这样它将重建所有内容并且我的 UI 与数据一致,但没有任何反应。

我发现重建不会再次重新创建BookButton小部件。 他们的构造函数不再被调用。 这就是为什么我的更新值没有得到接受,因为我将它们传递给BookButton的构造函数。

任何人都可以解释为什么会发生这种情况以及我如何正确显示选择了哪些交易而没有选择哪些交易?

交易小部件

class DealsWidget extends StatefulWidget {

  final List<Deal> _deals;
  final List<Deal> _selectedDeals;

  final DealSelectionListener _dealSelectionListener;

  DealsWidget(
    Key dealsKey,
    this._deals,
    this._selectedDeals,
    this._dealSelectionListener,
  ) : super(key: dealsKey);

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

class DealsWidgetState extends State<DealsWidget> {

  @override
  Widget build(BuildContext context) {

    final totalDeals = widget._deals.length;

    return ListView.builder(
      physics: NeverScrollableScrollPhysics(),
      itemCount: totalDeals,
      shrinkWrap: true,
      itemBuilder: (context, index) {

        final deal = widget._deals[index];
        final isSelected = widget._selectedDeals.contains(deal);
        
        return Container(
          color: Colors.white,
          padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
          child: BookButton(
            isSelected,
            (isBooked) {
              if (isBooked) {
                widget._dealSelectionListener._onSelected(deal);
              } else {
                widget._dealSelectionListener._onDeselected(deal);
              }
            }
          ),
        );
      }
    );
  }

  void refresh() {

    print('Refreshing deals');

    setState(() {
      
    });
  }
}

图书按钮

class BookButton extends StatefulWidget {

  final bool isBooked;
  final OnBookChangedListener listener;

  BookButton(this.isBooked, this.listener);

  @override
  BookButtonClass createState() => BookButtonClass(isBooked);
}
  
class BookButtonClass extends State<BookButton> {

  bool isBooked;

  BookButtonClass(this.isBooked);

  void check(bool check) {
    setState(() {
      isBooked = check;
      widget.listener.call(isBooked);
    });
  }
  
  @override
  Widget build(BuildContext context) {
    return FlatButton(
      onPressed: (){
        setState(() {
          isBooked = !isBooked;
          widget.listener.call(isBooked);
        });
      },
      child: Text(
        isBooked ? AppStrings.unbook.toUpperCase() : AppStrings.book.toUpperCase(),
        style: TextStyle(
          color: isBooked ? AppColors.accentColor : Colors.white,
          fontSize: 12,
        ),
      ),
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(5),
        side: BorderSide(
          color: AppColors.accentColor,
          width: isBooked ? 1 : 0,
        )
      ),
      color: isBooked ? Colors.transparent : AppColors.accentColor,
    );
  }
}

在这种情况下,您应该使用 Provider,因为小部件需要知道何时重建。

或者,如果您认为 Provider 现在很难学习,请尝试在事件 ClickButton 上使用 SetState(),这应该可以解决

看看我在我的案例中做了什么

所以在我的 class 和数据中,我使用了 change changeNotifier

class PartnerControler extends ChangeNotifier {
....
changeNotifiers()
}

在显示 class 中我使用了这个

ChangeNotifierProvider(
                  create: (context) => partnerControler,
                  child: buildPartnerList(context),
                ),

 Widget buildPartnerList(BuildContext context) {
return Column(
      children: <Widget>[
Consumer<PartnerControler>(
          builder: (context, partnercontroler, child) {
return (Expanded(
              child: ListView.builder(
itemCount: partnerControler.partnerListFiltered.length,
..

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM