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(),目前还没有更好的解决办法,如果有大神知道更好的解决办法,希望一起交流讨论。