#flutter #dart
#флаттер #дротик
Вопрос:
Я создал простой экран, на котором отображаются статические данные списка, но теперь я пытаюсь показать ответ API в списке, но не знаю, как его показать
Это мой код
class _EventsState extends State<Events> {
dynamic _events = [];
dynamic isloader = false;
@override
initState() {
// TODO: implement initState
super.initState();
doSomeAsyncStuff();
}
Future<void> doSomeAsyncStuff() async {
setState((){isloader = true;});
final storage = new FlutterSecureStorage();
String value = await storage.read(key: 'token');
print(value);
String url = 'http://sublimeapi.netcodesolution.com/api/NewsAndEvents/';
String token = value;
final response = await http.get(url, headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token',
});
print('Token : ${token}');
dynamic eventData = json.decode(response.body);
print(eventData["Data"]); // this is the data need to show
setState((){
isloader = true;
var _event = eventData["Data"];
});
}
@override
Widget build(BuildContext context) {
double statusBarHeight = MediaQuery
.of(context)
.padding
.top;
return Expanded(
child: Container(
child: new CustomScrollView(
scrollDirection: Axis.vertical,
slivers: <Widget>[
new SliverAppBar(
backgroundColor: Colors.white,
expandedHeight: statusBarHeight * 5,
flexibleSpace: new FlexibleSpaceBar(
title: const Text(
'Event Lists',
textAlign: TextAlign.left,
style: TextStyle(fontSize: 20, color: Color(0xff343A40)),
),
),
),
isloader ? CircularProgressIndicator() : // user loader there
new SliverPadding(
padding: const EdgeInsets.symmetric(vertical: 2.0),
sliver: new SliverFixedExtentList(
itemExtent: 280.0,
delegate: new SliverChildBuilderDelegate(
(builder, index) => _buildListItem(index),
childCount: _events.length),
)),
],
),
),
);
}
Widget _buildListItem(int index) {
double statusBarHeight = MediaQuery.of(context).padding.top;
double width = MediaQuery.of(context).size.width;
double height = MediaQuery.of(context).size.height;
return GestureDetector(
child: Center(
child: Card(
margin: EdgeInsets.zero,
clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
elevation: 30,
child: Container(
child: Stack(
children: <Widget>[
Container(
width: width * 0.6,
height: height * 0.17,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
'assets/images/61.jpg',
),
fit: BoxFit.fill,
),
),
),
Padding(
padding: EdgeInsets.only(top: height * 0.17),
child: Container(
height: height * 0.15,
color: Colors.white,
width: MediaQuery.of(context).size.width * 0.6,
child: Padding(
padding: const EdgeInsets.only(
top: 30, bottom: 7, left: 15, right: 15),
child: Row(
children: <Widget>[
Flexible(
child: Text(
_events[index]['Description'],
style: TextStyle(
color: Color(0xff343A40),
fontFamily: 'OpenSans',
fontWeight: FontWeight.bold,
fontSize: 15),
),
),
],
),
),
),
),
Positioned.fill(
child: Align(
alignment: Alignment.centerLeft,
child: Container(
margin: EdgeInsets.only(left: width * 0.02),
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(12)),
child: Container(
height: height * 0.08,
width: width * 0.4,
color: Color(0xff343A40),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
_events[index]['CreatedOn']
.substring(0, 10),
style: TextStyle(
fontSize: 20,
color: Color(0xffFFFFFF),
fontFamily: 'OpenSans',
fontWeight: FontWeight.bold),
),
]),
),
),
)),
),
],
),
),
),
),
);
}
}
Вы можете видеть в коде, что я показываю список статических данных _events, я вызываю данные из api, который работает абсолютно нормально, и печатаю данные, вы можете увидеть эту строку в коде, print(eventData["Data"]);
но проблема в том, что если я сделаю это вот так final List _events = eventData["Data"]
, чтобы показать данные api, а не статические данные, они отображают ошибку, я думаю, что api вызывается перед отображением данных.
Комментарии:
1. попробуйте удалить
final
из вашейfinal List _events
переменной, а затем используйтеsetState((){_events = eventData["Data"]; });
2. @Vitor я пытаюсь, но показываю ошибку об ошибке: средство получения ‘_events’ не определено для класса ‘_EventsState’. Похоже, что данные вызываются с опозданием, и я вызываю _events раньше
Ответ №1:
вы можете использовать это.
dynamic _events = [];
dynamic isloader = false;
Future<void> doSomeAsyncStuff() async {
setState((){isloader = true});
final storage = new FlutterSecureStorage();
String value = await storage.read(key: 'token');
print(value);
String url = 'http://sublimeapi.netcodesolution.com/api/NewsAndEvents/';
String token = value;
final response = await http.get(url, headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token',
});
print('Token : ${token}');
dynamic eventData = json.decode(response.body);
print(eventData["Data"]); // this is the data need to show
setState((){isloader = true,
_event = eventData["Data"];
});
}
@override
Widget build(BuildContext context) {
double statusBarHeight = MediaQuery.of(context).padding.top;
return Expanded(
child: Container(
child: new CustomScrollView(
scrollDirection: Axis.vertical,
slivers: <Widget>[
new SliverAppBar(
backgroundColor: Colors.white,
expandedHeight: statusBarHeight * 5,
flexibleSpace: new FlexibleSpaceBar(
title: const Text(
'Event Lists',
textAlign: TextAlign.left,
style: TextStyle(fontSize: 20, color: Color(0xff343A40)),
),
),
),
isLoader? CircularProgressIndicator() : // user loader there
new SliverPadding(
padding: const EdgeInsets.symmetric(vertical: 2.0),
sliver: new SliverFixedExtentList(
itemExtent: 280.0,
delegate: new SliverChildBuilderDelegate(
(builder, index) => _buildListItem(index),
childCount: _events.length),
)),
],
),
),
);
}
Комментарии:
1. Попробуйте ваш ответ, но не знаете, что он показывает какую-то ошибку в setState я добавил скриншот ошибки, о которой идет речь
2. проверьте теперь код еще раз, дайте мне знать. Это моя ошибка изменить setState функции
3. Попробуйте показать эту ошибку: RenderViewport ожидал дочернего элемента типа RenderSliver, но получил дочерний элемент типа RenderErrorBox.