Home > OS >  Listview is showing only after I hot reload or refresh in flutter
Listview is showing only after I hot reload or refresh in flutter

Time:02-11

I almost tried everything. My functions async, my snapshots async. I'm using future builders, My carousel slider works fine. I don't need to hot reload or refresh for carousel slider. But for my listview builder i need to refresh every time to fetch data. I tried connection state status for if statment but connection state getting done quickly (before data completely loaded). So my pictures and my datas not coming without refresh or hot reload.

import 'package:cached_network_image/cached_network_image.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

import 'package:video_games/model.dart';
import 'package:flutter/material.dart';
import 'package:video_games/send_models.dart';
import 'package:video_games/views/details_view.dart';
import 'package:get/get.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';

class HomePage extends StatefulWidget {
  HomePage({
    Key? key,
  }) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  Future<Autogenerated> apiCall() async {
    final response = await http.get(Uri.parse(
        'https://api.rawg.io/api/games?key=5ac29048d12d45d0949c77038115cb56&page=1'));

    return Autogenerated.fromJson(jsonDecode(response.body));
  }

  int slideractiveindex = 0;
  var urlImages = [];
  var uniqueImages = [];
  var growableList = [];
  var listId = [];

  @override
  Widget build(BuildContext context) {
    clearCache();

    return SingleChildScrollView(
      child: Column(
        children: [
          FutureBuilder<Autogenerated>(
            future: apiCall(),
            builder: (BuildContext context, AsyncSnapshot snapshot) {
              List<Results>? data = snapshot.data!.results;
              return Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  CarouselSlider.builder(
                    itemCount: 20,
                    itemBuilder: (context, index, realIndex) {
                      urlImages.add(data![index].backgroundImage);
                      uniqueImages = urlImages.toSet().toList();

                      final urlImage = uniqueImages[index];
                      return buildImage(urlImage, index);
                    },
                    options: CarouselOptions(
                        autoPlay: true,
                        enlargeCenterPage: true,
                        onPageChanged: (index, reason) {}),
                  ),
                  const SizedBox(height: 32),
                ],
              );
            },
          ),
          FutureBuilder<Autogenerated>(
            future: apiCall(),
            builder: (BuildContext context, AsyncSnapshot snapshot) {
              if (snapshot.hasData) {
                print(snapshot.connectionState);
                print(urlImages.length);
                List<Results>? data = snapshot.data!.results;

                return ListView.builder(
                  physics: NeverScrollableScrollPhysics(),
                  shrinkWrap: true,
                  itemBuilder: (BuildContext context, index) {
                    growableList.add(data![index].name);
                    listId.assign(data[index].id);

                    // String? id = data[index].id.toString();
                    // urlImages.add(data[index].backgroundImage);
                    uniqueImages = urlImages.toSet().toList();
                    final urlImage = uniqueImages[index   1];
                    return Padding(
                      padding: const EdgeInsets.all(10.0),
                      child: ListTile(
                        tileColor: Colors.black12,
                        leading: InkWell(
                            onTap: () {
                              Navigator.push(
                                  context,
                                  MaterialPageRoute(
                                    builder: (context) => DetailsPage(
                                      id: '${data[index].id}',
                                    ),
                                  ));
                            },
                            child: buildImage2(urlImage, index)),
                        title: Column(
                          children: [
                            Text(
                              '${data[index].name}',
                            ),
                            Row(
                              mainAxisAlignment: MainAxisAlignment.center,
                              children: [
                                Text('Rating : ${data[index].rating}'),
                                SizedBox(
                                  width: 20,
                                ),
                                Text('Release : ${data[index].released}'),
                              ],
                            )
                          ],
                        ),
                      ),
                    );
                  },
                  itemCount: 19,
                );
              } else {
                return CircularProgressIndicator();
              }
            },
          ),
        ],
      ),
    );
  }

  Widget buildImage(String? urlImage, int index) {
    return Container(
        margin: EdgeInsets.symmetric(horizontal: 12),
        color: Colors.grey,
        child: CachedNetworkImage(
          imageUrl: urlImage!,
          fit: BoxFit.cover,
          key: UniqueKey(),
          errorWidget: (context, url, error) => Icon(Icons.error),
          placeholder: (context, url) => Container(
            child: Center(
              child: CircularProgressIndicator(),
            ),
          ),
        ));
  }

  Widget buildImage2(String? urlImage, int index) {
    return Container(
        height: 100,
        width: 100,
        child: CachedNetworkImage(
          imageUrl: urlImage!,
          key: UniqueKey(),
          fit: BoxFit.cover,
          errorWidget: (context, url, error) => Icon(Icons.error),
          placeholder: (context, url) => Container(
            child: Center(
              child: CircularProgressIndicator(),
            ),
          ),
        ));
  }

  void clearCache() {
    DefaultCacheManager().emptyCache();
    imageCache!.clear();
    imageCache!.clearLiveImages();
    setState(() {});
  }
}

This is my error part

════════ Exception caught by widgets library ═══════════════════════════════════
RangeError (index): Invalid value: Valid value range is empty: 17
════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════
RangeError (index): Invalid value: Valid value range is empty: 18
════════════════════════════════════════════════════════════════════════════════




Before i reload After i reloaded

CodePudding user response:

FutureBuilder removes boilerplate code. see

Let's say you want to fetch some data from the backend on page launch and show a loader until data comes.

Tasks for ListBuilder:

  • Have two state variables, dataFromBackend and isLoadingFlag On

  • launch, set isLoadingFlag = true, and based on this, show loader.

  • Once data arrives, set data with what you get from backend and set
    isLoadingFlag = false (inside setState obviously)

  • We need to have a if-else in widget creation. If isLoadingFlag is true,show the loader else show the data. On failure, show error message.

Tasks for FutureBuilder:

  • Give the async task in future of Future Builder
  • Based on connectionState, show message (loading, active(streams), done)
  • Based on data(snapshot.hasError), show view

Pros of FutureBuilder

  • Does not use the two state variables and setState
  • Reactive programming (FutureBuilder will take care of updating the view on data arrival)

Example:

FutureBuilder<String>(
future: _fetchNetworkCall, // async work
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
   switch (snapshot.connectionState) {
     case ConnectionState.waiting: return Text('Loading....');
     default:
       if (snapshot.hasError)
          return Text('Error: ${snapshot.error}');
       else
      return Text('Result: ${snapshot.data}');
    }
  },
)
  • Related