Flutter: создание ListView после запроса http.get - PullRequest
0 голосов
/ 03 марта 2019

Я чувствую, что эта проблема не должна занять более 6 часов, чтобы понять, но здесь я после долгих поисков и игры с кодомПо сути, когда я перехожу на страницу, будущее автоматически отправляет запрос http.get от _getData ().Я получаю данные и создаю ListView очень хорошо, проблема в том, что я хочу, чтобы ListView строил только ПОСЛЕ того, как поисковый запрос был отправлен из TextField.Любая помощь будет принята с благодарностью!

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

class FutureBuilderTestPage extends StatefulWidget {
  @override
  BuilderTestPageState createState() => BuilderTestPageState();
}

class BuilderTestPageState extends State {
  static String _searchTerm = "";
  String _url = "https://api.nal.usda.gov/ndb/search/?format=json&q=$_searchTerm&sort=n&max=20&offset=0&api_key=OMITTEDforThisPost";
  @override
  Widget build(BuildContext context) {
    var _futureBuilder = new FutureBuilder(
        future: _getData(),
        builder: (BuildContext context, AsyncSnapshot 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 createMyListView(context, snapshot);
            }
            return null; // unreachable
        });
    return new Scaffold(
        appBar: new AppBar(
          title: Text("Appbar"),
        ),
        body: Column(
          children: <Widget>[
            Text("Search for food..."),
            TextField(
              decoration: InputDecoration(hintText: 'Search here'),
              onSubmitted: (String valueIn) {
                _searchTerm = valueIn;
              },
            ),
            Text("Results for... " + _searchTerm),
            Divider(height: 4.0),
            Expanded(child: _futureBuilder),
          ],
        ));
  }

  Future<List<dynamic>> _getData() async {
    http.Response response = await http.get(_url,
        headers: {"Accept": "Application/json"});

    final data = jsonDecode(response.body) as Map;
    final mapOfList = data['list'] as Map;
    final listOfItem = mapOfList['item'] as List<dynamic>;

    print(listOfItem.toString());

    var values = new List<dynamic>();
    for (var e in listOfItem) {
      values.add(e);
    }
    return values;
  }

  Widget createMyListView(BuildContext context, AsyncSnapshot snapshot) {
    List<dynamic> values = snapshot.data;
    return new ListView.builder(
      itemCount: values.length,
      itemBuilder: (BuildContext context, int index) {
        return new Column(
          children: <Widget>[
            new ListTile(
              title: new Text(values[index]['name']),
            )
          ],
        );
      },
    );
  }
}

class FoodObjectFromJson {
  final int offset;
  final String group;
  final String name;
  final int ndbno;
  final String ds;
  final String manu;

  FoodObjectFromJson(
      this.offset, this.group, this.name, this.ndbno, this.ds, this.manu);
}

1 Ответ

0 голосов
/ 03 марта 2019

Чтобы ответить на ваш вопрос, я несколько упростил / изменил код, поэтому веб-вызов не требуется.

Обратите внимание на объявление переменной bool "show_results".Это ключ к тому, что вы хотите сделать.Убедитесь, что вы отметили все варианты использования переменной.

Внутри двух конструкций setState () он сначала отключает видимость / существование вашего желаемого списка, а затем после того, как ваш поиск был выполнен, он включает видимость / существование вашего желаемого списка.

Этот код был протестирован и работает, как показано.

Надеюсь, это поможет.

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

class zFutureBuilderTestPage extends StatefulWidget {
  @override
  zBuilderTestPageState createState() => zBuilderTestPageState();
}

class zBuilderTestPageState extends State {
  static String _searchTerm = "";

  bool show_results=false;

  String _url = "https://www.awebsite.com/search.php";
  @override
  Widget build(BuildContext context) {
    var _futureBuilder = new FutureBuilder(
        future: _getData(),
        builder: (BuildContext context, AsyncSnapshot 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 createMyListView(context, snapshot);
          }
          return null; // unreachable
        });
    return new Scaffold(
        appBar: new AppBar(
          title: Text("Appbar"),
        ),
        body: Column(
          children: <Widget>[
            Text("Search for food..."),
            TextField(
              decoration: InputDecoration(hintText: 'Search here'),
              onSubmitted: (String valueIn) => search(valueIn),
            ),
            Text("Results for... " + _searchTerm),
            Divider(height: 4.0),
            show_results == false ? new Container ( width: 0, height: 0 ) : Expanded(child: _futureBuilder),
          ],
        ));
  }

  Future <List<dynamic>> search ( String valueIn ) async {
    print (valueIn);
    setState(() {
      show_results=false;
    });

    List<dynamic> l = await _getData();

    setState(() {
      show_results=true;
    });
    return ( l );
  }

  Future<List<dynamic>> _getData() async {

    List<FoodObjectFromJson> values=new List();
    FoodObjectFromJson H =new FoodObjectFromJson(5,"Orange");
    values.add( H );
    FoodObjectFromJson H2 =new FoodObjectFromJson(8,"Apple");
    values.add( H2 );
    FoodObjectFromJson H3 =new FoodObjectFromJson(22,"Pear");
    values.add( H3 );


    return values;
  }

  Widget createMyListView(BuildContext context, AsyncSnapshot snapshot) {
    List<dynamic> values = snapshot.data;
    return new ListView.builder(
      itemCount: values.length,
      itemBuilder: (BuildContext context, int index) {
        return new Column(
          children: <Widget>[
            new ListTile(
              title: new Text(values[index].fruit_handle),
            )
          ],
        );
      },
    );
  }
}

class FoodObjectFromJson {
  final int fruit_id;
  final String fruit_handle;

  FoodObjectFromJson(
      this.fruit_id, this.fruit_handle);
}
...