infinite_loop_list 1.0.0 copy "infinite_loop_list: ^1.0.0" to clipboard
infinite_loop_list: ^1.0.0 copied to clipboard

A simple and lightweight Flutter widget for creating **infinite looping lists** with optional **auto-scroll** support. Perfect for carousels, banners, news tickers, and any scrollable content that sho [...]

example/lib/main.dart

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:infinite_loop_list/infinite_loop_list.dart';
import 'package:http/http.dart' as http;
void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Infinite Loop List Demo',
      theme: ThemeData(primarySwatch: Colors.green),
      scrollBehavior: MyCustomScrollBehavior(),
      home: const DemoScreen(),
    );
  }
}

class DemoScreen extends StatelessWidget {
  const DemoScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Infinite Auto Scroll List")),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          Center(
            child: ElevatedButton(
              style: ElevatedButton.styleFrom(
                backgroundColor: Colors.blue,
                foregroundColor: Colors.white
              ),
                onPressed: () {
              Navigator.push(context, MaterialPageRoute(builder: (context) {
                return VerticalListScreen();
              },));
            }, child: Text('Vertical List')),
          ),
          SizedBox(height: 30,),

          Center(
            child: ElevatedButton(
              style: ElevatedButton.styleFrom(
                backgroundColor: Colors.blue,
                foregroundColor: Colors.white
              ),
                onPressed: () {
              Navigator.push(context, MaterialPageRoute(builder: (context) {
                return HorizontalListScreen();
              },));
            }, child: Text('Horizontal List')),
          ),
        ],
      ),
    );
  }
}
class VerticalListScreen extends StatefulWidget {
  const VerticalListScreen({super.key});

  @override
  State<VerticalListScreen> createState() => _VerticalListScreenState();
}

class _VerticalListScreenState extends State<VerticalListScreen> {

  late Future<List<Product>> futureProducts;

  @override
  void initState() {
    super.initState();
    futureProducts = fetchProducts();
  }

  Future<List<Product>> fetchProducts() async {
    final response = await http.get(Uri.parse('https://fakestoreapi.com/products'));

    if (response.statusCode == 200) {
      List jsonResponse = json.decode(response.body);
      return jsonResponse.map((data) => Product.fromJson(data)).toList();
    } else {
      throw Exception('Failed to load products');
    }
  }



  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Infinite Loop List Vertical'),
      ),
      body: FutureBuilder(
        future: futureProducts,
        builder: (context, snapshot) {
          if(snapshot.hasData) {
            List<Product> products = snapshot.data!;
            return InfiniteLoopList(
            scrollDirection: Axis.vertical,
            scrollSpeed: 3.0,
            enableAutoScroll: false,
            pauseDuration: const Duration(seconds: 3),
            padding: const EdgeInsets.all(16),
                itemBuilder: (context, index) {
                  Product product = products[index];
                  return Card(
                    margin: const EdgeInsets.symmetric(vertical: 8),
                    child: ListTile(
                      leading: ClipRRect(
                        borderRadius: BorderRadius.circular(8),
                        child: Image.network(
                          product.image,
                          width: 60,
                          height: 60,
                          fit: BoxFit.cover,
                          errorBuilder: (context, error, stackTrace) {
                            return const Icon(Icons.error, color: Colors.red);
                          },
                        ),
                      ),
                      title: Text(
                        product.title,
                        maxLines: 2,
                        overflow: TextOverflow.ellipsis,
                        style: const TextStyle(fontWeight: FontWeight.bold),
                      ),
                      subtitle: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          const SizedBox(height: 4),
                          Text(
                            '\$${product.price}',
                            style: const TextStyle(
                              color: Colors.green,
                              fontWeight: FontWeight.bold,
                              fontSize: 16,
                            ),
                          ),
                          Text(
                            product.category,
                            style: TextStyle(color: Colors.grey[600]),
                          ),
                        ],
                      ),
                      trailing: const Icon(Icons.arrow_forward_ios, size: 16),
                      onTap: () {
                        // می‌تونی صفحه جزئیات محصول رو اینجا باز کنی
                        ScaffoldMessenger.of(context).showSnackBar(
                          SnackBar(content: Text('انتخاب شد: ${product.title}')),
                        );
                      },
                    ),
                  );
                }, itemCount: products.length,
          );
          }else if (snapshot.hasError) {
            return Center(child: Text('خطا: ${snapshot.error}'));
          }
          return const Center(child: CircularProgressIndicator());
        }
      ),
    );
  }
}



class HorizontalListScreen extends StatefulWidget {
  const HorizontalListScreen({super.key});

  @override
  State<HorizontalListScreen> createState() => _HorizontalListScreenState();
}

class _HorizontalListScreenState extends State<HorizontalListScreen> {

  late Future<List<Product>> futureProducts;

  @override
  void initState() {
    super.initState();
    futureProducts = fetchProducts();
  }

  Future<List<Product>> fetchProducts() async {
    final response = await http.get(Uri.parse('https://fakestoreapi.com/products'));

    if (response.statusCode == 200) {
      List jsonResponse = json.decode(response.body);
      return jsonResponse.map((data) => Product.fromJson(data)).toList();
    } else {
      throw Exception('Failed to load products');
    }
  }



  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Infinite Loop List Horizontal'),
      ),
      body: Column(
        children: [

          FutureBuilder(
              future: futureProducts,
              builder: (context, snapshot) {
                if(snapshot.hasData) {
                  List<Product> products = snapshot.data!;
                  return SizedBox(
                    height: 250,
                    child: InfiniteLoopList(
                      itemCount: products.length,
                      scrollDirection: Axis.horizontal,
                      scrollSpeed: 3.0,
                      pauseDuration: const Duration(seconds: 1),
                      padding: const EdgeInsets.all(16),
                      itemBuilder: (context, index) {
                        Product product = products[index];
                        return Container(
                          width: 160, // عرض هر آیتم
                          margin: const EdgeInsets.only(right: 12),
                          child: Card(
                            elevation: 4,
                            shape: RoundedRectangleBorder(
                              borderRadius: BorderRadius.circular(12),
                            ),
                            child: InkWell(
                              borderRadius: BorderRadius.circular(12),
                              onTap: () {
                                ScaffoldMessenger.of(context).showSnackBar(
                                  SnackBar(content: Text('انتخاب شد: ${product.title}')),
                                );
                              },
                              child: Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  // تصویر محصول
                                  ClipRRect(
                                    borderRadius: const BorderRadius.vertical(top: Radius.circular(12)),
                                    child: Image.network(
                                      product.image,
                                      height: 100,
                                      width: double.infinity,
                                      fit: BoxFit.cover,
                                      errorBuilder: (context, error, stackTrace) {
                                        return Container(
                                          height: 100,
                                          color: Colors.grey[300],
                                          child: const Icon(Icons.error, color: Colors.red),
                                        );
                                      },
                                    ),
                                  ),
                                  // اطلاعات محصول
                                  Padding(
                                    padding: const EdgeInsets.all(8.0),
                                    child: Column(
                                      crossAxisAlignment: CrossAxisAlignment.start,
                                      children: [
                                        Text(
                                          product.title,
                                          maxLines: 2,
                                          overflow: TextOverflow.ellipsis,
                                          style: const TextStyle(
                                            fontSize: 13,
                                            fontWeight: FontWeight.bold,
                                          ),
                                        ),
                                        const SizedBox(height: 4),
                                        Text(
                                          '\$${product.price}',
                                          style: const TextStyle(
                                            color: Colors.green,
                                            fontWeight: FontWeight.bold,
                                            fontSize: 14,
                                          ),
                                        ),
                                        const SizedBox(height: 2),
                                        Text(
                                          product.category,
                                          style: TextStyle(
                                            fontSize: 11,
                                            color: Colors.grey[600],
                                          ),
                                          maxLines: 1,
                                          overflow: TextOverflow.ellipsis,
                                        ),
                                      ],
                                    ),
                                  ),
                                ],
                              ),
                            ),
                          ),
                        );
                      },
                    ),
                  );
                }else if (snapshot.hasError) {
                  return Center(child: Text('خطا: ${snapshot.error}'));
                }
                return const Center(child: CircularProgressIndicator());
              }
          ),
        ],
      ),
    );
  }
}


class Product {
  final int id;
  final String title;
  final double price;
  final String description;
  final String category;
  final String image;

  Product({
    required this.id,
    required this.title,
    required this.price,
    required this.description,
    required this.category,
    required this.image,
  });

  factory Product.fromJson(Map<String, dynamic> json) {
    return Product(
      id: json['id'],
      title: json['title'],
      price: json['price'].toDouble(),
      description: json['description'],
      category: json['category'],
      image: json['image'],
    );
  }
}
2
likes
150
points
56
downloads

Publisher

unverified uploader

Weekly Downloads

A simple and lightweight Flutter widget for creating **infinite looping lists** with optional **auto-scroll** support. Perfect for carousels, banners, news tickers, and any scrollable content that should repeat infinitely.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on infinite_loop_list