简体   繁体   中英

Only one item is appearing at a time on list view

I cant seem to figure out how to get all of my items in my list to display in the list view

Currently, when I click my button to display the list, only one items shows up. If I click back, and click main button again, it shows 2 items from the list. Rinse and repeat, 3 items. I can't seem to debug with print statements to see where my error lies. When I try print(trails) or other variations, it says Instance of trail model (not very helpful). Any ideas?

Here's my code:

class HomeScreen extends State<MyApp> {
  int counter = 0;
  Future<List<TrailModel>> fetchData() async {
    counter++;
    var response = await get(
        'https://www.hikingproject.com/data/get-trails?lat=39.733694&lon=-121.854771&maxDistance=10&key=200419778-6a46042e219d019001dd83b13d58aa59');

    final trailModel = TrailModel.fromJson(json.decode(response.body));
    //trails.add(trailModel);
    setState(() {
      trails.add(trailModel);
    });

    return trails;
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
      appBar: AppBar(title: Text("HikeLocator")),
      body: new RaisedButton(
        child: Text("click me"),
        onPressed: () async {
          final trails = await fetchData();
          Navigator.push(
            context,
            new MaterialPageRoute(builder: (context) => new ListScreen(trails)),
          );
        },
      ),
    ));
  }
}

class ListScreen extends StatelessWidget {
  final List<TrailModel> trails;
  ListScreen(this.trails);

  @override
  Widget build(BuildContext ctxt) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Here are your trails"),
      ),
      body: TrailList(trails),
    );
  }
}

class TrailList extends StatelessWidget {
  final List<TrailModel> trails;

  TrailList(this.trails);

  Widget build(context) {
    return ListView.builder(
      itemCount: trails.length,
      itemBuilder: (context, int index) {
        Object myText = json.encode(trails[index].trails);

        List<dynamic> myText2 = json.decode(myText);

        return Text(myText2[index]['name']);
      },
    );
  }
}

class TrailModel {
  Object trails;
  TrailModel(this.trails);
  TrailModel.fromJson(Map<String, dynamic> parsedJson) {
    trails = parsedJson['trails'];
  }
}

I think my problem might lie in the fetchData(), but I'm not entirely sure. Trying to at least print out the values to limit where my problem might be. (Is it only adding 1 to the list each time I press the button? Is it only rendering one when I click it? Is it fetching all the data each click or only one json object? etc.)

Thank you kindly for any assistance. Sorry, I'm kind of new to dart, so this is a huge learning curve for

There are a couple problems in your code. The main reason this doesn't work as you expect is because you're parsing all elements of the json into one TrailModel object, but then your code assumes that you'll have multiple TrailModel objects.

The easiest way to fix it up and get it working is to use the list from TrailModel.trails instead of the one in the widget.

First, in ListScreen , pass just the first element in the list.

class ListScreen extends StatelessWidget {
  final List<TrailModel> trails;
  ...
  @override
  Widget build(BuildContext ctxt) {
    return new Scaffold(
      ...
      body: TrailList(trails.first),
    );
  }
}

Then, in TrailList , use the trails list you have from TrailModel :

class TrailList extends StatelessWidget {
  final TrailModel model;
  TrailList(this.model);

  Widget build(context) {
    return ListView.builder(
      itemCount: model.trails.length,
      itemBuilder: (context, int index) {
        final trail = model.trails[index];
        ...
      },
    );
  }
}

When I try print(trails) or other variations, it says Instance of trail model (not very helpful)

print uses the output of the toString method in your classes. You're seeing Instance of trail model because that's the default implementation you get from the super class Object . You can override it to get something more useful:

class TrailModel {
  @override
  String toString() => 'trails=$trails';
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM