問題描述
自行更新的 Flutter 模型 (Flutter model that updates itself)
為了開發我的應用程序,我想使用我創建的模型,因為我必須在 3 個頁面中顯示這個小部件。
這個小部件有一個函數,當點擊小部件時調用它以及一個文本和點擊按鈕時應該改變的顏色。這應該僅在列表 items
的 userID
時發生(這些項目是用戶數據列表並且列表的結構類似於 [{''userID' : 'keykeykey, 'userName': 'Ryan', ...}, {..}, {..}])等於登錄用戶的
userID`。
對於這個問題的目的我創建了一個小部件(但原來的部件中有很多東西
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class SomeRandomCard extends StatelessWidget {
SomeRandomCard({@required this.onPressed, this.text, this.color});
final GestureTapCallback onPressed;
String text;
Color color;
@override
Widget build(BuildContext context) {
return RawMaterialButton(
child: Text(text,
style: TextStyle(
color: color
),),
onPressed: onPressed,
);
}
}
我在 ListView.builder<中調用 SomeRandomCard 小部件
參考解法
方法 1:
Here is the real problem betweeen
SomeRandomCard(onPressed: changeText(items[index]['userID']), text: text, color: color,);
and
SomeRandomCard(onPressed: changeText, text: text, color: color,);
The first one, you pass a void
or nothing(null
) to onPressed
because you called changeText
, and changeText return void
.
The second one works because you passed an actual function
instead of null
or void
.
According to your requirement.
the function is been called and change the value on the screen. But I have to check if the userId is the same, how can I do it?
You could do It as below:
@override
Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: style.coral,
body: Container(
child: ListView.builder
(
itemCount: items.length,
itemBuilder: (BuildContext ctxt, int index) {
return SomeRandomCard(onPressed: () { changeText(items[index]['userID']) }, text: text, color: color,);
}
)
),
floatingActionButton: MyFloatingButton(),
);
}
By the way, It might be confusion on the preservation of index
. I had this confusion before, so I provide a minimal exmaple, you could try It on DartPad to see how It works.
class TestCallback {
final Function onPress;
TestCallback(this.onPress);
call() {
onPress();
}
}
main(){
List<TestCallback> callbacks = new List<TestCallback>();
for(int i = 0; i < 5; i++)
callbacks.add(TestCallback((){ print(i); }));
for(int i = 0; i < 5; i++)
callbacks[i].call();
}
Output: 0 1 2 3 4
方法 2:
Here is the fix:
Don't do this:
onPressed: widget.onPressed
Do this:
onPressed: () => widget.onPressed()
Here is the complete code for you:
import 'package:flutter/material.dart';
main() {
runApp(MyStateWidget());
}
class MyStateWidget extends StatefulWidget {
@override
_MyStateWidgetState createState() => _MyStateWidgetState();
}
class _MyStateWidgetState extends State<MyStateWidget> {
var userID = 'TestTestTestTestTestTestTest';
String text = 'a';
Color color = Colors.green;
changeText(someID) {
debugPrint("changeText");
if (someID == userID) {
setState(() {
debugPrint(text);
if (text == 'a') {
text = 'b';
color = Colors.green;
} else {
text = 'a';
color = Colors.red;
}
});
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
child: ListView.builder(
itemCount: 1,
itemBuilder: (BuildContext ctxt, int index) {
return SomeRandomCard(
onPressed: () => changeText(items[index]['userID']),
text: text,
color: color,
);
})),
floatingActionButton: FloatingActionButton(
onPressed: () {print("Hello");},
),
),
);
}
}
class SomeRandomCard extends StatelessWidget {
SomeRandomCard({@required this.onPressed, this.text, this.color});
final Function onPressed;
String text;
Color color;
@override
Widget build(BuildContext context) {
return RawMaterialButton(
child: Text(
text,
style: TextStyle(color: color),
),
onPressed: () => onPressed(),
);
}
}
方法 3:
I think you just change onPressed: changeText(items[index]['userID'])
to onPressed: ()=>changeText(items[index]['userID'])
will work.
(by alessandro buffoli、Tokenyet、sagar suri、mafanwei)
參考文件