1

我正在尝试在使用 Future Builder 从 api 获取数据的列表中添加收藏按钮。但是,当我单击InkWell小部件以标记为我的收藏时,它会重新加载列表,收藏按钮的颜色不会改变,而且 setState 似乎也不会改变_isFavorite

未来建设者

Widget build(BuildContext context) {
return Scaffold(
  appBar: AppBar(
      leading: IconButton(
        icon: Icon(Icons.arrow_back),
        onPressed: () => Navigator.of(context).pop(),
      ),
      title: FittedBox(fit: BoxFit.fill, child: Text(getTranslated(context, 'derangement'))),
      backgroundColor: Colors.red),
  backgroundColor: Color(0xfff0f0f0),
  body: Column(
    mainAxisAlignment: MainAxisAlignment.start,
    children: <Widget>[
      SizedBox(height: 20),
      buildHeader(widget.productName, Colors.lightBlue),
      SizedBox(height: 20),
      FutureBuilder<List>(
        future: vapi.getDerangement(widget.endpoint, widget.productId),
        initialData: List(),
        builder: (context, snapshot) {
          return futureHandler(snapshot, context, _expansionTile(snapshot));
        },
      ),
    ],
  ),
 );
}

列表显示

Widget _expansionTile(AsyncSnapshot snapshot) {
return Flexible(
    child: ListView.builder(
  padding: const EdgeInsets.all(10.0),
  itemCount: snapshot.data == null ? 0 : snapshot.data.length,
  scrollDirection: Axis.vertical,
  shrinkWrap: true,
  itemBuilder: (context, i) {
    bool _isFavourite = snapshot.data[i].isFavourite;
    return Row(
      children: <Widget>[
        InkWell(
          splashColor: Colors.yellow,
          highlightColor: Colors.red,
          child: Icon(
            _isFavourite ? Icons.favorite : Icons.favorite_border,
            size: 40,
            color: _isFavourite ? Colors.red : null,
          ),
          onTap: () {
            setState(() {
              _isFavourite = !_isFavourite;
            });
          },
        ),
        Expanded(
            child: SingleChildScrollView(
                child: Container(
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(25),
            color: Colors.white54,
          ),
          child: ExpansionTile(
            title:
                Text(snapshot.data[i].substanceName, style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
            subtitle: Text(snapshot.data[i].name),
            children: <Widget>[
              SizedBox(
                height: 200,
                child: SingleChildScrollView(child: Text(snapshot.data[i].references)),
              ),
            ],
          ),
          margin: EdgeInsets.symmetric(vertical: 10, horizontal: 2),
          padding: EdgeInsets.symmetric(vertical: 5, horizontal: 5),
        )))
      ],
    );
  },
 ));
}
4

1 回答 1

2
future: vapi.getDerangement(widget.endpoint, widget.productId),

不要那样做。这将调用此方法并在每次调用该方法时生成一个build的未来。

在 initState 中调用此方法并将返回值保存在变量中。然后把这个变量传递给FutureBuilder,所以如果build被多次调用,它仍然是同一个future,而不是每次都是一个新的future。

于 2020-11-19T13:53:56.920 回答