我是Flutter的新人,
我想破坏最初创建的卡,并根据API调用中提供的数据再次构建它们
基本上当我点击UI中的按钮时,它应该调用API并基于来自API调用的数据,如果它与我已有的数据不同,我想要破坏卡并再次构建它们。
我怎么能做到这一点?
答案 0 :(得分:1)
当您再次拨打电话时,这些卡会自动更新其内容,就像刷新您的数据一样。
我做了一个简单的示例,其中一张卡片显示来自this JSON的数据我在initState
第一次调用API,然后每次按下FAB时重复调用。< / p>
我正在添加索引变量只是为了向您显示更新(使用列表中的下一项更新我的单张卡)
另外值得注意的是,我为了时间而处理空值或空值。
还要忘记UI溢出¯_(ツ)_ /¯
class CardListExample extends StatefulWidget {
@override
_CardListExampleState createState() => new _CardListExampleState();
}
class _CardListExampleState extends State<CardListExample> {
Map cardList = {};
int index = 0;
@override
void initState() {
_getRequests();
super.initState();
}
_getRequests() async {
String url = "https://jsonplaceholder.typicode.com/users";
var httpClinet = createHttpClient();
var response = await httpClinet.get(
url,
);
var data = JSON.decode(response.body);
//print (data);
setState(() {
this.cardList = data[index];
this.index++;
});
print(cardList);
print(cardList["name"]);
}
@override
Widget build(BuildContext context) {
return new Scaffold(
floatingActionButton:
new FloatingActionButton(onPressed: () => _getRequests()),
appBar: new AppBar(
title: new Text("Card List Example"),
),
body: this.cardList != {}
? new ListView(children: <Widget>[
new Card(
child: new Column(
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
new Text(
cardList["name"] ?? '',
style: Theme.of(context).textTheme.display1,
),
new Text(
this.cardList['email'] ?? '',
maxLines: 50,
),
],
),
new Text(cardList["website"] ?? '')
],
),
),
])
: new Center(child: new CircularProgressIndicator()),
);
}
}
答案 1 :(得分:1)
是的,来自Aziza的回答 虽然我使用了以下代码:
void main() =>
runApp(new MaterialApp(
onGenerateRoute: (RouteSettings settings) {
switch (settings.name) {
case '/about':
return new FromRightToLeft(
builder: (_) => new _aboutPage.About(),
settings: settings,
);
}
},
home : new HomePage(),
theme: new ThemeData(
fontFamily: 'Poppins',
primarySwatch: Colors.blue,
),
));
class HomePage extends StatefulWidget{
@override
HomePageState createState() => new HomePageState();
}
class HomePageState extends State<HomePage>{
List data;
Future<String> getData() async{
var response = await http.get(
Uri.encodeFull(<SOMEURL>),
headers: {
"Accept" : "application/json"
}
);
this.setState((){
data = JSON.decode(response.body);
});
return "Success";
}
@override
void initState() {
// TODO: implement initState
super.initState();
this.getData();
}
@override
Widget build(BuildContext context){
return new Scaffold(
appBar : new AppBar(
title : new Text("ABC API"),
actions: <Widget>[
new IconButton( // action button
icon: new Icon(Icons.cached),
onPressed: () => getData(),
)],
),
drawer: new Drawer(
child: new ListView(
children: <Widget> [
new Container(
height: 120.0,
child: new DrawerHeader(
padding: new EdgeInsets.all(0.0),
decoration: new BoxDecoration(
color: new Color(0xFFECEFF1),
),
child: new Center(
child: new FlutterLogo(
colors: Colors.blueGrey,
size: 54.0,
),
),
),
),
new ListTile(
leading: new Icon(Icons.chat),
title: new Text('Support'),
onTap: () {
Navigator.pop(context);
Navigator.of(context).pushNamed('/support');
}
),
new ListTile(
leading: new Icon(Icons.info),
title: new Text('About'),
onTap: () {
Navigator.pop(context);
Navigator.of(context).pushNamed('/about');
}
),
new Divider(),
new ListTile(
leading: new Icon(Icons.exit_to_app),
title: new Text('Sign Out'),
onTap: () {
Navigator.pop(context);
}
),
],
)
),
body: this.data != null ?
new ListView.builder(
itemCount: data.length,
itemBuilder: (BuildContext context, int index){
return new Container(
padding: new EdgeInsets.fromLTRB(8.0,5.0,8.0,0.0),
child: new Card(
child: new Padding(
padding: new EdgeInsets.fromLTRB(10.0,12.0,8.0,0.0),
child: new Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new ListTile(
enabled: data[index]['active'] == '1' ? true : false,
title: new Text(data[index]['header'],
style:Theme.of(context).textTheme.headline,
),
subtitle: new Text("\n" + data[index]['description']),
),
new ButtonTheme.bar(
child: new ButtonBar(
children: <Widget>[
new FlatButton(
child: new Text(data[index]['action1']),
onPressed: data[index]['active'] == '1' ? _launchURL :null,
),
],
),
),
],
),
),
),
);
},
)
:new Center(child: new CircularProgressIndicator()),
);
}
}
_launchURL() async {
const url = 'http://archive.org';
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
class FromRightToLeft<T> extends MaterialPageRoute<T> {
FromRightToLeft({ WidgetBuilder builder, RouteSettings settings })
: super(builder: builder, settings: settings);
@override
Widget buildTransitions(
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child) {
if (settings.isInitialRoute)
return child;
return new SlideTransition(
child: new Container(
decoration: new BoxDecoration(
boxShadow: [
new BoxShadow(
color: Colors.black26,
blurRadius: 25.0,
)
]
),
child: child,
),
position: new Tween(
begin: const Offset(1.0, 0.0),
end: const Offset(0.0, 0.0),
)
.animate(
new CurvedAnimation(
parent: animation,
curve: Curves.fastOutSlowIn,
)
),
);
}
@override Duration get transitionDuration => const Duration(milliseconds: 400);
}
以上代码包括导航抽屉,页面导航动画以及上述问题的答案。