gpt4 book ai didi

listview - Flutter 仅按需填充 ExpansionTile 数据(一个 Future 对象),而不是在初始化时

转载 作者:IT王子 更新时间:2023-10-29 06:40:02 25 4
gpt4 key购买 nike

我能够从 REST/JSON 填充 ListView 和 ExpansionTiles,这很好,但我希望扩展 block 最初不填充,并且仅在单击它们时单独填充(可能使用 onExpansionChanged:)

我有以下内容,它几乎像我想要的那样工作,除了它正在填充 ListView,然后由于每个 ExpansionTile 内的 FutureBuilder,它会立即(自动)填充扩展图 block 。

如何更改此设置,以便在单独单击/展开之前不会填充 ExpansionTiles?

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

void main() {
runApp(new MyApp());
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'ExpansionTile Test',
home: new MyHomePage(),
);
}
}

class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
Future<http.Response> _responseFuture;

@override
void initState() {
super.initState();
_responseFuture = http.get('https://jsonplaceholder.typicode.com/users');
print("Getting Main List");
}

@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('ExpansionTile Test'),
),
body: new FutureBuilder(
future: _responseFuture,
builder: (BuildContext context, AsyncSnapshot<http.Response> response) {
if (!response.hasData) {
return const Center(
child: const Text('Loading...'),
);
} else if (response.data.statusCode != 200) {
return const Center(
child: const Text('Error loading data'),
);
} else {
List<dynamic> jsonn = json.decode(response.data.body);
return new MyExpansionTileList(jsonn);
}
},
),
);
}
}

class MyExpansionTileList extends StatelessWidget {
final List<dynamic> elementList;

MyExpansionTileList(this.elementList);

List<Widget> _getChildren() {
List<Widget> children = [];
elementList.forEach((element) {
children.add(
new MyExpansionTile(element['id'], element['name']),
);
});
return children;
}

@override
Widget build(BuildContext context) {
return new ListView(
children: _getChildren(),
);
}
}

class MyExpansionTile extends StatefulWidget {
final int id;
final String title;
MyExpansionTile(this.id, this.title);
@override
State createState() => new MyExpansionTileState();
}

class MyExpansionTileState extends State<MyExpansionTile> {
PageStorageKey _key;
Future<http.Response> _responseFuture;

@override
void initState() {
super.initState();
_responseFuture = http.get('https://jsonplaceholder.typicode.com/users');
print("Getting Expansion Item # ${widget.id}");
}

@override
Widget build(BuildContext context) {
_key = new PageStorageKey('${widget.id}');
return new ExpansionTile(
key: _key,
title: new Text(widget.title),
children: <Widget>[
new FutureBuilder(
future: _responseFuture,
builder:
(BuildContext context, AsyncSnapshot<http.Response> response) {
if (!response.hasData) {
return const Center(
child: const Text('Loading...'),
);
} else if (response.data.statusCode != 200) {
return const Center(
child: const Text('Error loading data'),
);
} else {
List<dynamic> json_data = json.decode(response.data.body);
List<Widget> reasonList = [];
json_data.forEach((element) {
reasonList.add(new ListTile(
dense: true,
title: new Text(element['email']),
));
});
return new Column(children: reasonList);
}
},
)
],
);
}
}

最佳答案

您可以使用 Completer而不是 Future,但仍然使用 FutureBuilder,这里是示例代码

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

void main() {
runApp(new MyApp());
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'ExpansionTile Test',
home: new MyHomePage(),
);
}
}

class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
Future<http.Response> _responseFuture;

@override
void initState() {
super.initState();
_responseFuture = http.get('https://jsonplaceholder.typicode.com/users');
print("Getting Main List");
}

@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('ExpansionTile Test'),
),
body: new FutureBuilder(
future: _responseFuture,
builder: (BuildContext context, AsyncSnapshot<http.Response> response) {
if (!response.hasData) {
return const Center(
child: const Text('Loading...'),
);
} else if (response.data.statusCode != 200) {
return const Center(
child: const Text('Error loading data'),
);
} else {
List<dynamic> jsonn = json.decode(response.data.body);
return new MyExpansionTileList(jsonn);
}
},
),
);
}
}

class MyExpansionTileList extends StatelessWidget {
final List<dynamic> elementList;

MyExpansionTileList(this.elementList);

List<Widget> _getChildren() {
List<Widget> children = [];
elementList.forEach((element) {
children.add(
new MyExpansionTile(element['id'], element['name']),
);
});
return children;
}

@override
Widget build(BuildContext context) {
return new ListView(
children: _getChildren(),
);
}
}

class MyExpansionTile extends StatefulWidget {
final int id;
final String title;
MyExpansionTile(this.id, this.title);
@override
State createState() => new MyExpansionTileState();
}

class MyExpansionTileState extends State<MyExpansionTile> {
PageStorageKey _key;
Completer<http.Response> _responseCompleter = new Completer();

@override
Widget build(BuildContext context) {
_key = new PageStorageKey('${widget.id}');
return new ExpansionTile(
key: _key,
title: new Text(widget.title),
onExpansionChanged: (bool isExpanding) {
if (!_responseCompleter.isCompleted) {
_responseCompleter.complete(http.get('https://jsonplaceholder.typicode.com/users'));
print("Getting Expansion Item # ${widget.id}");
}
},
children: <Widget>[
new FutureBuilder(
future: _responseCompleter.future,
builder:
(BuildContext context, AsyncSnapshot<http.Response> response) {
if (!response.hasData) {
return const Center(
child: const Text('Loading...'),
);
} else if (response.data.statusCode != 200) {
return const Center(
child: const Text('Error loading data'),
);
} else {
List<dynamic> json_data = json.decode(response.data.body);
List<Widget> reasonList = [];
json_data.forEach((element) {
reasonList.add(new ListTile(
dense: true,
title: new Text(element['email']),
));
});
return new Column(children: reasonList);
}
},
)
],
);
}
}

关于listview - Flutter 仅按需填充 ExpansionTile 数据(一个 Future 对象),而不是在初始化时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54976939/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com