2021-03-25

Flutter 局部刷新界面出现的问题 === There are multiple heroes that share the same tag within a subtree

#做一个根据单选框的选项实现局部刷新,我们知道的使用setState()的来进行刷新,是重新渲染整个界面,而且使用setState()会占用内存,所以我选择了ValueNotifier来实现局部的刷新,而Radio的值改变时,我们一般用的setState()来实现值的变化和界面的刷新,为了减少内存的占用,我使用了ValueNotifier,但是我的child中是写一个从手机中选择图片并显示到界面上的,也是需要进行刷新的,所以在ValueListenableBuilder中就会再嵌套一个ValueListenableBuilder,此时就出现问题了。

代码如下:
ValueListenableBuilder(
valueListenable: _resultNotifier,
 builder: (BuildContext context, List<AssetEntity> value, Widget child) {
 return Column(
        children: [
          Container(
            //height: 82,
            color: Colors.white,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Container(
                    alignment: Alignment.centerLeft,
                    decoration: BoxDecoration(
                      border: Border(
                        bottom: BorderSide(
                          width: 0.75,
                          color: AppTheme.of(context).dividerColor,
                        ),
                      ),
                    ),
                    padding:
                    EdgeInsets.only(top: 10, left: 10, bottom: 10),
                    child: Row(
                      children: [
                        Container(
                          height: 20,
                          width: 4,
                          color: CupertinoTheme.of(context).primaryColor,
                        ),
                        Container(
                          padding: EdgeInsets.only(left: 5),
                          child:
                          Text(appS.lottery_order_page_item_result),
                        )
                      ],
                    )),
                Container(
                  padding: EdgeInsets.only(left: 20, right: 20),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.start,
                    children: [
                      Row(
                        children: [
                          Radio(
                            value: 0,
                            groupValue: groupValue,
                            activeColor:
                            CupertinoTheme.of(context).primaryColor,
                            onChanged: (v) {
                            _resultNotifier.value = v;
                              groupValue = v;
                              debugPrint(
                                  groupValue.toString());
                            },
                          ),
                          Text(appS.lottery_order_cash_cash_not_award),
                        ],
                      ),
                      Row(
                        children: [
                          Radio(
                            value: 1,
                            groupValue: groupValue,
                            activeColor:
                            CupertinoTheme.of(context).primaryColor,
                            onChanged: (v) {
                            _resultNotifier.value = v;
                              groupValue = v;
                              debugPrint(
                                  groupValue.toString());
                            },
                          ),
                          Text(appS.lottery_order_is_award),
                        ],
                      )
                    ],
                  ),
                )
              ],
            ),
          ),
          groupValue == 0
              ? Expanded(
            child: Column(
              children: [
                SizedBox(
                  height: 5,
                ),
                Container(
                  //height: 200,
                  color: Colors.white,
                  child: Column(
                    children: [
                      Container(
                          alignment: Alignment.centerLeft,
                          decoration: BoxDecoration(
                            border: Border(
                              bottom: BorderSide(
                                width: 0.75,
                                color: AppTheme.of(context).dividerColor,
                              ),
                            ),
                          ),
                          padding:
                          EdgeInsets.only(top: 10, left: 10, bottom: 10),
                          child: Row(
                            children: [
                              Container(
                                height: 20,
                                width: 4,
                                color: CupertinoTheme.of(context).primaryColor,
                              ),
                              Container(
                                padding: EdgeInsets.only(left: 5),
                                child:
                                Text(appS.lottery_order_cash_result_update),
                              )
                            ],
                          )),
                      ValueListenableBuilder(
                          valueListenable: _assets,
                          builder: (BuildContext context, List<AssetEntity> value, Widget child) {
                            return Container(
                              padding: EdgeInsets.only(top: 10,bottom: 5),
                              height: 140,
                              child: GridView.builder(
                                padding: EdgeInsets.only(right: 10, left: 10),
                                scrollDirection: Axis.horizontal,
                                gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                                    crossAxisCount: 1,
                                    crossAxisSpacing: 10,
                                    mainAxisSpacing: 10,
                                    childAspectRatio: 1),
                                itemCount: value == null
                                    ? 1
                                    : value.length >= 3
                                    ? value.length
                                    : value.length + 1,
                                itemBuilder: (BuildContext context, int index) {
                                  if (value != null) {
                                    if (index == value.length) {
                                      return InkWell(
                                        child: Container(
                                          decoration: BoxDecoration(
                                            border:
                                            Border.all(color: Colors.grey, width: 1),
                                            borderRadius: BorderRadius.circular(8),
                                          ),
                                          width: 100,
                                          height: 100,
                                          child: Center(
                                            child: Icon(
                                              Icons.camera_alt,
                                              color: Colors.grey,
                                              size: 50,
                                            ),
                                          ),
                                        ),
                                        onTap: () {
                                          _showCupertinoActionSheet(context);
                                        },
                                      );
                                    } else {
                                      AssetEntity asset = value[index];
                                      return _loadImg(asset, index);
                                    }
                                  } else {
                                    return InkWell(
                                      child: Container(
                                        decoration: BoxDecoration(
                                          border: Border.all(color: Colors.grey, width: 1),
                                          borderRadius: BorderRadius.circular(8),
                                        ),
                                        width: 100,
                                        height: 100,
                                        child: Center(
                                          child: Icon(
                                            Icons.camera_alt,
                                            color: Colors.grey,
                                            size: 50,
                                          ),
                                        ),
                                      ),
                                      onTap: () {
                                        _showCupertinoActionSheet(context);
                                      },
                                    );
                                  }
                                },
                              ),
                            );
                          }
                      ),
                    ],
                  ),
                ),
              ],
            ),
          )
              : Container(),
          SafeArea(
            child: SizedBox(
              width: MediaQuery.of(context).size.width,
              height: 44 + MediaQuery.of(context).padding.bottom,
              child: CupertinoButton(
                padding: EdgeInsets.all(0),
                color: CupertinoTheme.of(context).primaryColor,
                child: Text(
                  appS.merchant_submit,
                  style: TextStyle(color: Colors.black),
                ),
                onPressed: () {},
              ),
            ),
          )
        ],
      );
 }
),

修改之后,去掉了最外层的ValueListenableBuilder,Radio中还是使用了setState(),目前还没有更好的解决办法,如果有大神知道更好的解决办法,希望一起交流讨论。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值