Из будущегов Список <String>для вызовов API для использования в обычных функциях / скаффолдах - PullRequest
0 голосов
/ 28 октября 2019

Я использую TMDb API для отображения URL изображений. Я могу получить URL-адреса изображений и отобразить их на консоли. Но затем, когда я пытаюсь создать метод и выполнить цикл для каждого из элементов в списке, он продолжает возвращаться пустым (я проверил с печатью).

Редактировать: Оба метода находятся внутри одного класса и буквально нижедруг друга.

Буду признателен за любую помощь!

List<String> popularMovie = List<String>();

  @override
  void initState() {
    super.initState();
    this.getJsonData();
  }

  //GET POPULAR MOVIE INFO WITH API
  Future<List> getJsonData() async {
    http.Response response = await http.get(
      Uri.encodeFull(popularURL),
      headers: {
        'Accept': 'application/json'
      }
    );


    var popularMovieData = json.decode(response.body);
    var placeholder = popularMovieData['results'];


    //get a list of images only
    for(var item in placeholder) {
      popularMovie.add(item['poster_path']);
   }
    print(popularMovie.length); //20
    print(popularMovie); //prints [imgURL, imageURL, ...]
    return popularMovie;

  } //end of popular movie api function

Ниже приведен метод, который предполагает циклический просмотр элементов списка

//method to iterate through each item and get the image url to display image
  List<Widget> popularMovies() {
    List<Widget> popularMovieList = new List();

  for(var item in popularMovie) { //this is empty
    var popularMovieItem = Padding(
    padding: EdgeInsets.all(10),
    child: Container(
      width: 250,
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(15),
        color: Colors.white,
        boxShadow: [
          BoxShadow(
            color: Colors.grey.withOpacity(0.4),
            spreadRadius: 4,
            blurRadius: 4,
          ),
        ]
      ),
      child: Stack(
        children: <Widget>[
          Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              Container(
                height: MediaQuery.of(context).size.height/2 - 20,
                width: MediaQuery.of(context).size.width,
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.all(Radius.circular(15),),
                  image: DecorationImage(
                    image: NetworkImage('https://image.tmdb.org/t/p/w500${item}'),
                    fit: BoxFit.fill,
                  )
                ),
              ),
            ],
          ),
        ],
      ),
    ),
  );
  popularMovieList.add(popularMovieItem);
    }
    return popularMovieList;
  }

И, наконец, я 'я хочу показывать все фильмы на моей странице как

children:popularMovies(),

Ответы [ 2 ]

1 голос
/ 28 октября 2019

Поскольку getJsonData является асинхронной функцией, вам нужно использовать FutureBuider или вместо того, чтобы возвращать popularMovie, вам нужно вызвать setState

FutureBuilder<String>(
  future: getJsonData,
  builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
    switch (snapshot.connectionState) {
      case ConnectionState.none:
        return Text('Press button to start.');
      case ConnectionState.active:
      case ConnectionState.waiting:
        return Text('Awaiting result...');
      case ConnectionState.done:
        if (snapshot.hasError)
          return Text('Error: ${snapshot.error}');
        return Text('Result: ${snapshot.data}');
    }
    return null; // unreachable
  },
)
0 голосов
/ 28 октября 2019

Я наконец понял это! С setState это очень просто, поэтому если кому-то нужно решение для преобразования Future<List<String>> to List<String>, а затем использовать его как обычный список внутри скаффолда, вот что я сделал:

Сначала объявите переменную списка:

List<String> popularMovie = List<String>(); //declare a list inside the class

Затем выполните http-вызов и присвойте «список элементов, которые вы хотите» ранее объявленной переменной списка «внутри setState»

@override
  void initState() {
    super.initState();
    this.getJsonData();
  }

  //GET POPULAR MOVIE INFO WITH API
  Future<List<String>> getJsonData() async {
    http.Response response = await http.get(
      Uri.encodeFull(popularURL),
      headers: {
        'Accept': 'application/json'
      }
    );

    setState(() { //only get the first 10 movie images
      var popularMovieData = json.decode(response.body);
      for (int i = 0; i < 10; i++) {
        popularMovie.add(popularMovieData['results'][i]['poster_path']);      
      }
      print(popularMovie);
    });

  } //end of popular movie api function

Затем я создал метод для создания виджета дляотображать каждое изображение, которое совпадает с методом, который я создал в моем исходном посте, который начинается следующим образом:

List<Widget> popularMovies() {

И, наконец, я хотел показать это таким образом (что вы можете сделать, как хотите):

Padding(
            padding: EdgeInsets.only(left: 10, top: 10, bottom: 10),
            child: Container(
              height: MediaQuery.of(context).size.height/2,
              child: ListView(
                scrollDirection: Axis.horizontal,
                children: popularMovies(), //display all images in a horizontal row
              ),
            ),
          ),

И все готово! :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...