banner_slider 0.0.1 copy "banner_slider: ^0.0.1" to clipboard
banner_slider: ^0.0.1 copied to clipboard

Reusable Flutter video, image, text, banner and auto-playing slider widget.

example/lib/main.dart

import 'package:banner_slider/banner_slider.dart';
import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Banner Slider Example',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo),
      ),
      home: const ExampleHomePage(),
    );
  }
}

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

  static const List<BannerItem> _sliderItems = [
    BannerItem(
      title: 'Big Weekend Sale',
      badge: 'Video',
      deeplink: '/sale',
      media: BannerSliderMedia.video(
        url:
            'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4',
        playToEnd: true,
      ),
    ),
    BannerItem(
      title: 'Summer Collection',
      badge: 'Image',
      deeplink: '/collection',
      media: BannerSliderMedia.imageNetwork(
        url: 'https://picsum.photos/id/1020/1200/600',
        displayDuration: Duration(seconds: 2),
      ),
    ),
    BannerItem(
      title: 'Animated Promo',
      badge: 'GIF',
      deeplink: '/promo',
      media: BannerSliderMedia.imageNetwork(
        url: 'https://media.giphy.com/media/ICOgUNjpvO0PC/giphy.gif',
      ),
    ),
    BannerItem(
      title: 'Flutter Branding',
      badge: 'SVG',
      deeplink: '/svg',
      media: BannerSliderMedia.svgNetwork(
        url:
            'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/android.svg',
        displayDuration: Duration(seconds: 3),
      ),
    ),
  ];

  static const BannerItem _singleItem = BannerItem(
    title: 'Single Video Banner',
    badge: 'Single',
    deeplink: '/single',
    media: BannerSliderMedia.video(
      url:
          'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4',
    ),
  );

  static void _showTapSnackBar(BuildContext context, String message) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text(message), behavior: SnackBarBehavior.floating),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: const Text('Banner Slider Example'),
      ),
      body: ListView(
        padding: const EdgeInsets.symmetric(vertical: 16.0),
        children: [
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 16.0),
            child: Text(
              'Mixed Media BannerSlider',
              style: Theme.of(context).textTheme.titleMedium,
            ),
          ),
          const SizedBox(height: 12.0),
          BannerSlider<BannerItem>(
            items: _sliderItems,
            mediaBuilder: (item) => item.media,
            nonTimedItemDuration: const Duration(seconds: 3),
            defaultPlayVideoToEnd: true,
            padding: EdgeInsets.zero,
            contentPadding: const EdgeInsets.symmetric(
              horizontal: 12.0,
              vertical: 8.0,
            ),
            borderRadius: 0.0,
            loop: true,
            mediaFit: BoxFit.cover,
            dotActiveColor: Colors.white,
            dotInactiveColor: Colors.grey,
            dotsPosition: DotsPosition.bottomRight,
            itemBuilder: (context, index, muteState) {
              final item = _sliderItems[index];
              return _BannerCardContent(item: item, muteState: muteState);
            },
            onItemTap: (item) {
              _showTapSnackBar(
                context,
                'Tapped: ${item.title} (${item.deeplink ?? '-'})',
              );
            },
          ),
          const SizedBox(height: 24.0),
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 16.0),
            child: Text(
              'BannerSlider.single()',
              style: Theme.of(context).textTheme.titleMedium,
            ),
          ),
          const SizedBox(height: 12.0),
          SizedBox(
            height: 340,
            child: ListView(
              scrollDirection: Axis.horizontal,
              children: [
                BannerSlider<BannerItem>(
                  items: _sliderItems,
                  mediaBuilder: (item) => item.media,
                  nonTimedItemDuration: const Duration(seconds: 3),
                  defaultPlayVideoToEnd: true,
                  padding: EdgeInsets.zero,
                  contentPadding: const EdgeInsets.symmetric(
                    horizontal: 12.0,
                    vertical: 8.0,
                  ),
                  borderRadius: 0.0,
                  loop: true,
                  width: 200,
                  mediaFit: BoxFit.cover,
                  dotActiveColor: Colors.white,
                  dotInactiveColor: Colors.grey,
                  dotsPosition: DotsPosition.bottomRight,
                  itemBuilder: (context, index, muteState) {
                    final item = _sliderItems[index];
                    return _BannerCardContent(item: item, muteState: muteState);
                  },
                  onItemTap: (item) {
                    _showTapSnackBar(
                      context,
                      'Tapped: ${item.title} (${item.deeplink ?? '-'})',
                    );
                  },
                ),
                BannerSlider<BannerItem>.single(
                  item: _singleItem,
                  loop: true,
                  padding: EdgeInsets.zero,
                  contentPadding: const EdgeInsets.all(12.0),
                  borderRadius: 0.0,
                  aspectRatio: 9 / 16,
                  width: 200,
                  mediaFit: BoxFit.cover,
                  mediaBuilder: (item) => item.media,
                  itemBuilder: (context, index, muteState) {
                    return _BannerCardContent(
                      item: _singleItem,
                      muteState: muteState,
                    );
                  },
                  onItemTap: (item) {
                    _showTapSnackBar(
                      context,
                      'Tapped single banner: ${item.title}',
                    );
                  },
                ),
                BannerSlider<BannerItem>.single(
                  item: _singleItem,
                  loop: true,
                  padding: EdgeInsets.zero,
                  contentPadding: const EdgeInsets.all(12.0),
                  borderRadius: 0.0,
                  aspectRatio: 9 / 16,
                  width: 200,
                  mediaFit: BoxFit.cover,
                  mediaBuilder: (item) => item.media,
                  itemBuilder: (context, index, muteState) {
                    return _BannerCardContent(
                      item: _singleItem,
                      muteState: muteState,
                    );
                  },
                  onItemTap: (item) {
                    _showTapSnackBar(
                      context,
                      'Tapped single banner: ${item.title}',
                    );
                  },
                ),
              ],
            ),
          ),
          const SizedBox(height: 24.0),
          const Padding(
            padding: EdgeInsets.symmetric(horizontal: 16.0),
            child: Text(
              'Timing rules: non-video uses displayDuration or fallback. '
              'Video plays to end by default unless duration is provided.',
            ),
          ),
        ],
      ),
    );
  }
}

class BannerItem {
  final String title;
  final String? badge;
  final String? deeplink;
  final BannerSliderMedia media;

  const BannerItem({
    required this.title,
    required this.media,
    this.badge,
    this.deeplink,
  });
}

final class _BannerCardContent extends StatelessWidget {
  final BannerItem item;
  final BannerSliderMuteState muteState;

  const _BannerCardContent({required this.item, required this.muteState});

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: [
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            if (item.badge != null) _BannerBadge(label: item.badge!),
            if (muteState.canMute)
              IconButton(
                onPressed: muteState.toggle,
                style: IconButton.styleFrom(
                  foregroundColor: Colors.white,
                  backgroundColor: Colors.black.withValues(alpha: 0.25),
                ),
                icon: Icon(
                  muteState.muted
                      ? Icons.volume_off_rounded
                      : Icons.volume_up_rounded,
                ),
              ),
          ],
        ),
        Text(
          item.title,
          maxLines: 2,
          overflow: TextOverflow.ellipsis,
          style: Theme.of(context).textTheme.titleMedium?.copyWith(
            color: Colors.white,
            fontWeight: FontWeight.w700,
          ),
        ),
      ],
    );
  }
}

final class _BannerBadge extends StatelessWidget {
  final String label;

  const _BannerBadge({required this.label});

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 6.0),
      decoration: BoxDecoration(
        color: Colors.white.withValues(alpha: 0.2),
        borderRadius: BorderRadius.circular(999),
      ),
      child: Text(
        label,
        style: Theme.of(context).textTheme.labelMedium?.copyWith(
          color: Colors.white,
          fontWeight: FontWeight.w600,
        ),
      ),
    );
  }
}
1
likes
140
points
34
downloads

Documentation

API reference

Publisher

verified publisheriliyass-zamouri.ga

Weekly Downloads

Reusable Flutter video, image, text, banner and auto-playing slider widget.

Repository (GitHub)
View/report issues

Topics

#flutter #slider #carousel #banner #video

License

MIT (license)

Dependencies

flutter, flutter_svg, video_player, visibility_detector

More

Packages that depend on banner_slider