从列表中调用时不会更新 flutter 小部件
flutter widget not being updated when called from a list
我之前在这里问过一个关于小部件未更新的问题:
我得到了一个很好的答案,它向我解释了更多关于状态如何工作的信息,我进一步试验了一点,现在有一个问题,即即使我在 setstate 中更新状态,我在列表中的小部件也没有更新。
问题中未更新的Widget 是testBoxList 列表中添加到列表后的TestBoxNumber 小部件。我意识到,如果我将构建器更改为 return 小部件本身,而不是从它工作的列表中,我不确定为什么会这样!
再次感谢任何帮助,我希望这也能帮助面临同样问题的人:)
主页代码
class TestPage extends StatefulWidget {
static const id = "test_page";
@override
_TestPageState createState() => _TestPageState();
}
class _TestPageState extends State<TestPage> {
List testBoxList = [];
List testSlideList = [];
List testParamList = [];
void updateFunc(ind, newVal) {
setState(() {
testParamList[ind] = newVal;
});
}
void addSlider() {
setState(() {
double slideValue = 0;
testParamList.add(slideValue);
int boxIndex = testParamList.length - 1;
testBoxList.add(TestBoxNumber(
numberDisplay: testParamList,
boxIndex: boxIndex,
));
testSlideList.add(TestSlider(
testValue: testParamList,
updateFunc: updateFunc,
boxIndex: boxIndex,
));
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {
addSlider();
},
),
body: Padding(
padding: const EdgeInsets.all(30.0),
child: ListView(
children: [
Text("Test Page"),
// Builder for viewers
ListView.builder(
shrinkWrap: true,
physics: ClampingScrollPhysics(),
itemCount: testBoxList.length,
itemBuilder: (BuildContext ctx, int index) {
return testBoxList[index];
// return Text(testParamList[index].toString());
// return TestBoxNumber(
// numberDisplay: testParamList, boxIndex: index);
},
),
// Builder for sliders
ListView.builder(
shrinkWrap: true,
physics: ClampingScrollPhysics(),
itemCount: testSlideList.length,
itemBuilder: (BuildContext ctx, int index) {
return testSlideList[index];
},
),
],
),
),
);
}
}
TestBoxNumber 小部件
class TestBoxNumber extends StatelessWidget {
final List numberDisplay;
final int boxIndex;
TestBoxNumber({required this.numberDisplay, required this.boxIndex});
Widget build(BuildContext context) {
return Text(this.numberDisplay[this.boxIndex].toString());
}
}
滑块小部件
class TestSlider extends StatefulWidget {
List testValue;
dynamic updateFunc;
int boxIndex;
TestSlider({
required this.testValue,
required this.updateFunc,
required this.boxIndex,
});
@override
_TestSliderState createState() => _TestSliderState();
}
class _TestSliderState extends State<TestSlider> {
// double curValue = widget.testValue;
@override
Widget build(BuildContext context) {
double curValue = widget.testValue[widget.boxIndex];
return Slider(
activeColor: themeData.primaryColorLight,
value: curValue,
min: 0,
max: 100,
divisions: 50,
label: curValue.round().toString(),
onChanged: (double value) {
setState(() {
curValue = value;
});
widget.updateFunc(widget.boxIndex, value);
},
);
}
}
又是我)
好的,现在的问题是您正在使用存储在列表中的小部件,而不是再次创建小部件:
你不应该这样做:
ListView.builder(
shrinkWrap: true,
physics: ClampingScrollPhysics(),
itemCount: testBoxList.length,
itemBuilder: (BuildContext ctx, int index) {
return testBoxList[index];
// return Text(testParamList[index].toString());
// return TestBoxNumber(
// numberDisplay: testParamList, boxIndex: index);
},
)
但是 return 新的 TestBoxNumber 小部件(您实际上已经对它进行了评论,但不确定您为什么这样做):
ListView.builder(
shrinkWrap: true,
physics: ClampingScrollPhysics(),
itemCount: testBoxList.length,
itemBuilder: (BuildContext ctx, int index) {
return TestBoxNumber(numberDisplay: testParamList, boxIndex: index);
},
)
所以你将从头开始渲染小部件,而不是从内存(列表)中提取它并导致一些奇怪的事情。 Flutter 针对此类重新渲染进行了相当优化。
所以总结以上所有内容:只需将数据传递到构建方法中的小部件。不要将小部件存储在内存中以便以后重用。
UPD:您也可以将 double
(我们称之为 yourDoubleValue
)传递给 TestBoxNumber
而不是列表和索引。然后使用 Text('$yourDoubleValue');
我之前在这里问过一个关于小部件未更新的问题:
我得到了一个很好的答案,它向我解释了更多关于状态如何工作的信息,我进一步试验了一点,现在有一个问题,即即使我在 setstate 中更新状态,我在列表中的小部件也没有更新。
问题中未更新的Widget 是testBoxList 列表中添加到列表后的TestBoxNumber 小部件。我意识到,如果我将构建器更改为 return 小部件本身,而不是从它工作的列表中,我不确定为什么会这样!
再次感谢任何帮助,我希望这也能帮助面临同样问题的人:)
主页代码
class TestPage extends StatefulWidget {
static const id = "test_page";
@override
_TestPageState createState() => _TestPageState();
}
class _TestPageState extends State<TestPage> {
List testBoxList = [];
List testSlideList = [];
List testParamList = [];
void updateFunc(ind, newVal) {
setState(() {
testParamList[ind] = newVal;
});
}
void addSlider() {
setState(() {
double slideValue = 0;
testParamList.add(slideValue);
int boxIndex = testParamList.length - 1;
testBoxList.add(TestBoxNumber(
numberDisplay: testParamList,
boxIndex: boxIndex,
));
testSlideList.add(TestSlider(
testValue: testParamList,
updateFunc: updateFunc,
boxIndex: boxIndex,
));
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {
addSlider();
},
),
body: Padding(
padding: const EdgeInsets.all(30.0),
child: ListView(
children: [
Text("Test Page"),
// Builder for viewers
ListView.builder(
shrinkWrap: true,
physics: ClampingScrollPhysics(),
itemCount: testBoxList.length,
itemBuilder: (BuildContext ctx, int index) {
return testBoxList[index];
// return Text(testParamList[index].toString());
// return TestBoxNumber(
// numberDisplay: testParamList, boxIndex: index);
},
),
// Builder for sliders
ListView.builder(
shrinkWrap: true,
physics: ClampingScrollPhysics(),
itemCount: testSlideList.length,
itemBuilder: (BuildContext ctx, int index) {
return testSlideList[index];
},
),
],
),
),
);
}
}
TestBoxNumber 小部件
class TestBoxNumber extends StatelessWidget {
final List numberDisplay;
final int boxIndex;
TestBoxNumber({required this.numberDisplay, required this.boxIndex});
Widget build(BuildContext context) {
return Text(this.numberDisplay[this.boxIndex].toString());
}
}
滑块小部件
class TestSlider extends StatefulWidget {
List testValue;
dynamic updateFunc;
int boxIndex;
TestSlider({
required this.testValue,
required this.updateFunc,
required this.boxIndex,
});
@override
_TestSliderState createState() => _TestSliderState();
}
class _TestSliderState extends State<TestSlider> {
// double curValue = widget.testValue;
@override
Widget build(BuildContext context) {
double curValue = widget.testValue[widget.boxIndex];
return Slider(
activeColor: themeData.primaryColorLight,
value: curValue,
min: 0,
max: 100,
divisions: 50,
label: curValue.round().toString(),
onChanged: (double value) {
setState(() {
curValue = value;
});
widget.updateFunc(widget.boxIndex, value);
},
);
}
}
又是我)
好的,现在的问题是您正在使用存储在列表中的小部件,而不是再次创建小部件:
你不应该这样做:
ListView.builder(
shrinkWrap: true,
physics: ClampingScrollPhysics(),
itemCount: testBoxList.length,
itemBuilder: (BuildContext ctx, int index) {
return testBoxList[index];
// return Text(testParamList[index].toString());
// return TestBoxNumber(
// numberDisplay: testParamList, boxIndex: index);
},
)
但是 return 新的 TestBoxNumber 小部件(您实际上已经对它进行了评论,但不确定您为什么这样做):
ListView.builder(
shrinkWrap: true,
physics: ClampingScrollPhysics(),
itemCount: testBoxList.length,
itemBuilder: (BuildContext ctx, int index) {
return TestBoxNumber(numberDisplay: testParamList, boxIndex: index);
},
)
所以你将从头开始渲染小部件,而不是从内存(列表)中提取它并导致一些奇怪的事情。 Flutter 针对此类重新渲染进行了相当优化。
所以总结以上所有内容:只需将数据传递到构建方法中的小部件。不要将小部件存储在内存中以便以后重用。
UPD:您也可以将 double
(我们称之为 yourDoubleValue
)传递给 TestBoxNumber
而不是列表和索引。然后使用 Text('$yourDoubleValue');