hexsis_infinity_scroll_bloc 0.2.2 copy "hexsis_infinity_scroll_bloc: ^0.2.2" to clipboard
hexsis_infinity_scroll_bloc: ^0.2.2 copied to clipboard

BLoC/Cubit extension for hexsis_infinity_scroll with zero boilerplate and full scroll integration.

example/lib/main.dart

import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hexsis_infinity_scroll_bloc/hexsis_infinity_scroll_bloc.dart';

void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Hexsis Infinity Scroll - BLoC Example',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
        useMaterial3: true,
      ),
      home: const HomeScreen(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: const Text('BLoC/Cubit Integration'),
      ),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          _ExampleCard(
            title: 'BLoC ListView',
            description: 'Zero boilerplate with InfiniteScrollCubit',
            onTap:
                () => Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => const BlocListExample(),
                  ),
                ),
          ),
          _ExampleCard(
            title: 'BLoC GridView',
            description: 'Grid layout with cubit integration',
            onTap:
                () => Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => const BlocGridExample(),
                  ),
                ),
          ),
        ],
      ),
    );
  }
}

class _ExampleCard extends StatelessWidget {
  const _ExampleCard({
    required this.title,
    required this.description,
    required this.onTap,
  });

  final String title;
  final String description;
  final VoidCallback onTap;

  @override
  Widget build(BuildContext context) {
    return Card(
      margin: const EdgeInsets.only(bottom: 12),
      child: ListTile(
        title: Text(title, style: const TextStyle(fontWeight: FontWeight.bold)),
        subtitle: Text(description),
        trailing: const Icon(Icons.arrow_forward_ios, size: 16),
        onTap: onTap,
      ),
    );
  }
}

class ProductCubit extends InfiniteScrollCubit<Product> {
  @override
  Future<List<Product>> fetchPage(int page) async {
    return await ProductApi.fetchProducts(page);
  }
}

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

  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (context) => ProductCubit(),
      child: Scaffold(
        appBar: AppBar(
          title: const Text('BLoC ListView'),
          actions: [
            BlocBuilder<ProductCubit, InfiniteScrollState<Product>>(
              builder: (context, state) {
                return Padding(
                  padding: const EdgeInsets.all(16.0),
                  child: Center(
                    child: Text(
                      '${state.items.length} items',
                      style: const TextStyle(fontWeight: FontWeight.bold),
                    ),
                  ),
                );
              },
            ),
          ],
        ),
        body: InfiniteScrollBlocListView<Product, ProductCubit>(
          itemBuilder: (context, product, index) {
            return ProductListTile(product: product, index: index);
          },
          separatorBuilder: (context, index) => const Divider(height: 1),
        ),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (context) => ProductCubit(),
      child: Scaffold(
        appBar: AppBar(title: const Text('BLoC GridView')),
        body: InfiniteScrollBlocGridView<Product, ProductCubit>(
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 2,
            crossAxisSpacing: 12,
            mainAxisSpacing: 12,
            childAspectRatio: 0.75,
          ),
          itemBuilder: (context, product, index) {
            return ProductGridCard(product: product);
          },
        ),
      ),
    );
  }
}

class Product {
  final int id;
  final String name;
  final String description;
  final double price;

  Product({
    required this.id,
    required this.name,
    required this.description,
    required this.price,
  });
}

class ProductApi {
  static Future<List<Product>> fetchProducts(int page) async {
    await Future.delayed(const Duration(milliseconds: 800));

    if (page > 10) {
      return [];
    }

    return List.generate(20, (index) {
      final id = (page - 1) * 20 + index + 1;
      return Product(
        id: id,
        name: 'Product #$id',
        description: 'Description for product $id',
        price: Random().nextDouble() * 100 + 10,
      );
    });
  }
}

class ProductListTile extends StatelessWidget {
  const ProductListTile({
    required this.product,
    required this.index,
    super.key,
  });

  final Product product;
  final int index;

  @override
  Widget build(BuildContext context) {
    return ListTile(
      leading: CircleAvatar(child: Text('#${index + 1}')),
      title: Text(product.name),
      subtitle: Text(product.description),
      trailing: Text(
        '\$${product.price.toStringAsFixed(2)}',
        style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
      ),
    );
  }
}

class ProductGridCard extends StatelessWidget {
  const ProductGridCard({required this.product, super.key});

  final Product product;

  @override
  Widget build(BuildContext context) {
    return Card(
      clipBehavior: Clip.antiAlias,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          Expanded(
            child: Container(
              color: Colors.primaries[product.id % Colors.primaries.length],
              child: Center(
                child: Text(
                  '#${product.id}',
                  style: const TextStyle(
                    color: Colors.white,
                    fontSize: 32,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ),
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  product.name,
                  style: const TextStyle(fontWeight: FontWeight.bold),
                  maxLines: 1,
                  overflow: TextOverflow.ellipsis,
                ),
                const SizedBox(height: 4),
                Text(
                  '\$${product.price.toStringAsFixed(2)}',
                  style: TextStyle(
                    color: Theme.of(context).colorScheme.primary,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}
0
likes
160
points
566
downloads

Documentation

API reference

Publisher

verified publisherhexsis.com

Weekly Downloads

BLoC/Cubit extension for hexsis_infinity_scroll with zero boilerplate and full scroll integration.

Homepage

License

MIT (license)

Dependencies

flutter, flutter_bloc, hexsis_infinity_scroll

More

Packages that depend on hexsis_infinity_scroll_bloc