fluter banner

25 阅读1分钟
import 'package:flutter/material.dart';
import '../type/steps.dart';

class BannerB extends StatefulWidget {
  final TypeArrayItemD steps;

  const BannerB({super.key, required this.steps});

  @override
  State<BannerB> createState() => _BannerddfState();
}

class _BannerddfState extends State<BannerB> {
  final PageController _pageController = PageController(viewportFraction: 1.0);
  int _currentPage = 0;

  @override
  void initState() {
    super.initState();

    // 自动轮播(可选)
    // Future.delayed(Duration.zero, () {
    //   _autoScroll();
    // });
  }

  void _autoScroll() async {
    while (mounted) {
      await Future.delayed(const Duration(seconds: 3));
      if (_pageController.hasClients) {
        int nextPage = (_currentPage + 1) % widget.steps.list.length;
        _pageController.animateToPage(
          nextPage,
          duration: const Duration(milliseconds: 400),
          curve: Curves.easeInOut,
        );
      }
    }
  }

  @override
  void dispose() {
    _pageController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final items = widget.steps.list;

    return Container(
      width: double.infinity,
      height: 125,
      decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(10)),
      child: Column(
        children: <Widget>[

          Expanded(
            child: PageView.builder(
              controller: _pageController,
              itemCount: items.length,

              onPageChanged: (index) {
                setState(() {
                  _currentPage = index;
                });
              },
              itemBuilder: (context, index) {
                final item = items[index];
                return Row(

                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Image.network(
                      item.img!,
                      fit: BoxFit.cover,
                      width: 120,
                      height: 120,
                    ),
                    SizedBox(width: 10), // 加点间距
                    Expanded(  // 让文字部分占剩余宽度
                      child: Column(
                        mainAxisSize: MainAxisSize.min, // 避免撑满整个高度
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text(
                            '${item.title}',
                            style: TextStyle(fontWeight: FontWeight.bold),
                          ),
                          SizedBox(height: 6),
                          Text(
                            '${item.desc}',
                            style: TextStyle(letterSpacing: 1 ,fontSize: 12),
                            overflow: TextOverflow.ellipsis,
                            maxLines: 4, // 限制最大行数,防止超出
                          ),
                        ],
                      ),
                    ),
                  ],
                );

              },
            ),
          ),
          const SizedBox(height: 8),
          // 指示器
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: List.generate(items.length, (index) {
              return AnimatedContainer(
                duration: const Duration(milliseconds: 300),
                margin: const EdgeInsets.symmetric(horizontal: 3),
                width: _currentPage == index ? 8 : 8,
                height: _currentPage == index ? 8 : 8,
                decoration: BoxDecoration(
                  color: _currentPage == index
                      ? const Color(0xff009946)
                      : const Color(0xffe7e7e7),
                  shape: BoxShape.circle,
                ),
              );
            }),
          ),
        ],
      ),
    );
  }
}