我创建了一个示例,可以在其中动态添加元素到颤动列表视图。每个列表视图元素都有按钮和文本。当我添加新元素时,显示不正确的文本。我正在添加增量数据,并期望每个项目的值分别为1,2,3,4...。但是每个项目的值仅为1。同样,在特定项目上按下按钮的状态也不会保持,在我滚动列表之后,只会显示正确的值。
我们不能在listView中使用有状态的小部件吗? 。问题和代码如下
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<String> europeanCountries = [];
int _counter = 0;
int _perPage = 50;
ScrollController _myScrollController = ScrollController();
void _incrementCounter() async {
const ThreeSec = const Duration(seconds: 1);
this._counter++;
europeanCountries.insert(0, this._counter.toString());
print(europeanCountries);
setState(() {});
}
void getMoreData() {
print('adding More Product ');
europeanCountries.add("New Product");
setState(() {});
}
@override
void initState() {
// TODO: implement initState
super.initState();
_myScrollController.addListener(() {
double maxscroll = _myScrollController.position.maxScrollExtent;
double currentScroll = _myScrollController.position.pixels;
double delta = MediaQuery.of(context).size.height * 0.25;
print("mac Scroll Controller - " + maxscroll.toString());
print("Current Scroll Controller - " + currentScroll.toString());
print("delta Scroll Controller - " + delta.toString());
if ((maxscroll - currentScroll) < delta) {
getMoreData();
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: _myListView(context),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
Widget _myListView(BuildContext context) {
// backing data
return Container(
child: europeanCountries.length == 0
? Center(
child: Text('No Product to Display'),
)
: ListView.builder(
controller: _myScrollController,
itemCount: europeanCountries.length,
reverse: false,
itemBuilder: (context, index) {
return myContainer(
mytext: europeanCountries[index],
);
},
),
);
}
}
class myContainer extends StatefulWidget {
final String mytext;
const myContainer({Key key, this.mytext}) : super(key: key);
@override
_myContainerState createState() => _myContainerState(mytext);
}
class _myContainerState extends State<myContainer> {
final String mytext;
String _buttontext = "inprogress";
Color myClr = Colors.blue;
_changeText() {
setState(() {
_buttontext = "Done";
myClr = Colors.green;
});
}
_myContainerState(this.mytext);
@override
Widget build(BuildContext context) {
return Container(
height: 100,
decoration: BoxDecoration(
border: Border.all(color: Colors.blue[700]),
shape: BoxShape.rectangle,
borderRadius: BorderRadius.all(Radius.circular(8)),
),
margin: EdgeInsets.all(20),
child: Column(
children: <Widget>[
Text(mytext),
RaisedButton(
child: Text(_buttontext),
onPressed: _changeText,
color: myClr,
textColor: Colors.white,
padding: EdgeInsets.fromLTRB(10, 10, 10, 10),
splashColor: Colors.black,
)
],
),
);
}
}
答案 0 :(得分:1)
编辑 更新评论中提到的完整代码
使用Class
保持按钮color
代码段
class EuropeanCountries {
String myText;
String myButtonText;
Color myColor;
EuropeanCountries({
this.myText,
this.myButtonText,
this.myColor,
});
}
用于编辑的演示
完整代码进行编辑
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class EuropeanCountries {
String myText;
String myButtonText;
Color myColor;
EuropeanCountries({
this.myText,
this.myButtonText,
this.myColor,
});
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
List<EuropeanCountries> europeanCountries = [];
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
int _perPage = 50;
ScrollController _myScrollController = ScrollController();
void _incrementCounter() async {
const ThreeSec = const Duration(seconds: 1);
this._counter++;
europeanCountries.insert(0, EuropeanCountries(myText:this._counter.toString(), myButtonText: "inprogress", myColor: Colors.blue));
print(europeanCountries);
setState(() {});
}
void getMoreData() {
print('adding More Product ');
europeanCountries.add(EuropeanCountries(myText:this._counter.toString(), myButtonText: "inprogress", myColor: Colors.blue));
//europeanCountries.insert(0, EuropeanCountries(myText:this._counter.toString(), myButtonText: "", myColor: Colors.blue));
setState(() {});
}
@override
void initState() {
// TODO: implement initState
super.initState();
_myScrollController.addListener(() {
double maxscroll = _myScrollController.position.maxScrollExtent;
double currentScroll = _myScrollController.position.pixels;
double delta = MediaQuery.of(context).size.height * 0.25;
print("mac Scroll Controller - " + maxscroll.toString());
print("Current Scroll Controller - " + currentScroll.toString());
print("delta Scroll Controller - " + delta.toString());
if ((maxscroll - currentScroll) < delta) {
getMoreData();
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: _myListView(context),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
Widget _myListView(BuildContext context) {
// backing data
return Container(
child: europeanCountries.length == 0
? Center(
child: Text('No Product to Display'),
)
: ListView.builder(
controller: _myScrollController,
itemCount: europeanCountries.length,
reverse: false,
itemBuilder: (context, index) {
return myContainer(
index : index
);
},
),
);
}
}
class myContainer extends StatefulWidget {
final int index;
const myContainer({Key key, this.index}) : super(key: key);
@override
_myContainerState createState() => _myContainerState();
}
class _myContainerState extends State<myContainer> {
//final String mytext;
//String _buttontext = "inprogress";
//Color myClr = Colors.blue;
_changeText() {
setState(() {
europeanCountries[widget.index].myButtonText = "Done";
europeanCountries[widget.index].myColor= Colors.green;
});
}
//_myContainerState(this.mytext);
@override
Widget build(BuildContext context) {
return Container(
height: 100,
decoration: BoxDecoration(
border: Border.all(color: Colors.blue[700]),
shape: BoxShape.rectangle,
borderRadius: BorderRadius.all(Radius.circular(8)),
),
margin: EdgeInsets.all(20),
child: Column(
children: <Widget>[
Text(europeanCountries[widget.index].myText),
RaisedButton(
child: Text(europeanCountries[widget.index].myButtonText),
onPressed: _changeText,
color: europeanCountries[widget.index].myColor,
textColor: Colors.white,
padding: EdgeInsets.fromLTRB(10, 10, 10, 10),
splashColor: Colors.black,
)
],
),
);
}
}
您可以在下面复制粘贴运行完整代码
myContainer
扩展StatefulWidget
的使用方式不正确。
第1步:_myContainerState(mytext);
删除mytext
步骤2:注释// final String mytext;
步骤3:注释//__myContainerState(this.mytext);
步骤4:Text(widget.mytext)
添加widget.
工作演示
完整代码
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<String> europeanCountries = [];
int _counter = 0;
int _perPage = 50;
ScrollController _myScrollController = ScrollController();
void _incrementCounter() async {
const ThreeSec = const Duration(seconds: 1);
this._counter++;
europeanCountries.insert(0, this._counter.toString());
print(europeanCountries);
setState(() {});
}
void getMoreData() {
print('adding More Product ');
europeanCountries.add("New Product");
setState(() {});
}
@override
void initState() {
// TODO: implement initState
super.initState();
_myScrollController.addListener(() {
double maxscroll = _myScrollController.position.maxScrollExtent;
double currentScroll = _myScrollController.position.pixels;
double delta = MediaQuery.of(context).size.height * 0.25;
print("mac Scroll Controller - " + maxscroll.toString());
print("Current Scroll Controller - " + currentScroll.toString());
print("delta Scroll Controller - " + delta.toString());
if ((maxscroll - currentScroll) < delta) {
getMoreData();
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: _myListView(context),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
Widget _myListView(BuildContext context) {
// backing data
return Container(
child: europeanCountries.length == 0
? Center(
child: Text('No Product to Display'),
)
: ListView.builder(
controller: _myScrollController,
itemCount: europeanCountries.length,
reverse: false,
itemBuilder: (context, index) {
return myContainer(
mytext: europeanCountries[index],
);
},
),
);
}
}
class myContainer extends StatefulWidget {
final String mytext;
const myContainer({Key key, this.mytext}) : super(key: key);
@override
_myContainerState createState() => _myContainerState();
}
class _myContainerState extends State<myContainer> {
//final String mytext;
String _buttontext = "inprogress";
Color myClr = Colors.blue;
_changeText() {
setState(() {
_buttontext = "Done";
myClr = Colors.green;
});
}
//_myContainerState(this.mytext);
@override
Widget build(BuildContext context) {
return Container(
height: 100,
decoration: BoxDecoration(
border: Border.all(color: Colors.blue[700]),
shape: BoxShape.rectangle,
borderRadius: BorderRadius.all(Radius.circular(8)),
),
margin: EdgeInsets.all(20),
child: Column(
children: <Widget>[
Text(widget.mytext),
RaisedButton(
child: Text(_buttontext),
onPressed: _changeText,
color: myClr,
textColor: Colors.white,
padding: EdgeInsets.fromLTRB(10, 10, 10, 10),
splashColor: Colors.black,
)
],
),
);
}
}