skip to Main Content
ListView.builder(
  scrollDirection: Axis.horizontal,
  itemCount: 10,
  itemBuilder: (context, i) {
    return Padding(
      padding: const EdgeInsets.only(right: 20.0),
      child:  Hello()
    );
  },
),

How can I make Hello() only build once? I was using List.generate() and I saw that I had to use ListView.Builder() to make them build only once. But, it seems like it is not working. I can see that it is sending http requests as I scroll like List.generate().

2

Answers


  1. import 'package:flutter/material.dart';
    import 'package:http/http.dart' as http;
    import 'dart:convert';
    
    class MyListView extends StatefulWidget {
      @override
      _MyListViewState createState() => _MyListViewState();
    }
    
    class _MyListViewState extends State<MyListView> {
      Future<List<String>>? _futureData;
    
      @override
      void initState() {
        super.initState();
        _futureData = fetchData();
      }
    
      Future<List<String>> fetchData() async {
        // Simulate an HTTP request
        final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'));
        if (response.statusCode == 200) {
          final List<dynamic> data = json.decode(response.body);
          return data.map((item) => item['title'] as String).toList();
        } else {
          throw Exception('Failed to load data');
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return FutureBuilder<List<String>>(
          future: _futureData,
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return Center(child: CircularProgressIndicator());
            } else if (snapshot.hasError) {
              return Center(child: Text('Error: ${snapshot.error}'));
            } else if (!snapshot.hasData || snapshot.data!.isEmpty) {
              return Center(child: Text('No data available'));
            } else {
              final data = snapshot.data!;
              return ListView.builder(
                scrollDirection: Axis.horizontal,
                itemCount: data.length,
                itemBuilder: (context, i) {
                  return Padding(
                    padding: const EdgeInsets.only(right: 20.0),
                    child: Text(data[i]),
                  );
                },
              );
            }
          },
        );
      }
    }
    
    void main() {
      runApp(MaterialApp(home: Scaffold(body: MyListView())));
    }
    
    Login or Signup to reply.
  2. You should not load the data from server in the build function, This is not the proper way.

    1. Make a private function to load data:
    Future<List<String>> _loadData () async {
        List<String> _fetched = [];
    
        // http request ...
    
        return _fetched;
      }
    
    1. And a private variable to hold the data:
      List<String> _data = [];

    2. Make sure you call get the data at the initState:

     @override
      void initState() {
        // TODO: implement initState
        _data = _loadData();
        super.initState();
      }
    

    Ways to show the data:

    1. Using FutureBuilder
    2. Using .map function
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search