flutter 不同微件之间引用的变量值(指标)

63lcw9qa  于 2023-02-05  发布在  Flutter
关注(0)|答案(1)|浏览(128)

我有一个调用此carousel的调用,根据单击的微件,它显示不同的内容(通过contentUrls参数)。内容显示正常,但我尝试包含DotsIndicator小部件和位置(activePage)变量没有更新。它从引用中获取值。例如,如果我在一个小部件上移动到图像5,当我转到另一个轮播时,它从图像5而不是图像0开始。我不理解activePage变量如何通过setState工作。

import 'package:activo/widgets/video_player.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
import 'package:dots_indicator/dots_indicator.dart';

class Carousel extends StatefulWidget {
  const Carousel({super.key, required this.contentUrls});
  final String contentUrls;

  @override
  State<Carousel> createState() => _CarouselState();
}

class _CarouselState extends State<Carousel> {
  double activePage = 0.0;
  final GlobalKey _key = GlobalKey();

  @override
  Widget build(BuildContext context) {
    List<String> contentUrls = widget.contentUrls.split(' , ');

    return Column(
      children: [
        CarouselSlider(
          key: _key,
          options: CarouselOptions(
            height: 300.0,
            onPageChanged: (val, _) {
              setState(() {
                activePage = val * 1.0;
              });
            },
          ),
          items: contentUrls.map(
            (currentContent) {
              return Builder(
                builder: (BuildContext context) {
                  return Container(
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(15),
                      border: Border.all(
                        color: Colors.white,
                      ),
                    ),
                    width: MediaQuery.of(context).size.width,
                    margin: const EdgeInsets.symmetric(horizontal: 5.0),
                    child: ClipRRect(
                      borderRadius: BorderRadius.circular(15),
                      child: currentContent.contains('mp4')
                          ? VideoPlayerWidget(
                              videoUrl: currentContent,
                            )
                          : Image.network(
                              currentContent,
                              // will need to change it based on pictures for events
                              fit: BoxFit.fill,
                            ),
                    ),
                  );
                },
              );
            },
          ).toList(),
        ),
        Text('$activePage'),
        DotsIndicator(
          dotsCount: contentUrls.length,
          position: activePage,
        ),
      ],
    );
  }
}

谢谢!
我希望当我加载这个小部件时,activePage的值是0,或者至少是那个特定carousel的最后一个值(因为我有多个),而不是来自其他小部件的最后一个值。

jq6vz3qz

jq6vz3qz1#

下面是使用setState((){})调整为使用索引的基本代码。

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

class Carousel extends StatefulWidget {
  const Carousel({super.key, required this.contentUrls});

  final List<String> contentUrls;

  @override
  State<Carousel> createState() => _CarouselState();
}

class _CarouselState extends State<Carousel> {
  int activePage = 1;
  final GlobalKey _key = GlobalKey();

  _onPageChanged(int index) {
    activePage = index;
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        CarouselSlider(
            key: _key,
            options: CarouselOptions(
              height: 300.0,
              onPageChanged: (index, _) {
                _onPageChanged(index);
              },
            ),
            items: widget.contentUrls
                .map((e) => Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Container(
                        color: Colors.blue,
                        child: Center(child: Text(e)),
                      ),
                    ))
                .toList()),
      ],
    );
  }
}

此外,正如您在结尾提到的,您可能希望在再次加载页面时显示最后一张carousel卡片,为此,您可以使用一个包来保存页面索引,以管理应用状态,如Provider。
下面是使用Provider的示例(也使用从在线获取的GIF图像)。

import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => CarouselNotifier()),
      ],
      child: const MaterialApp(
        home:
        Material(child: Carousel(contentUrls: ['https://media.giphy.com/media/wW95fEq09hOI8/giphy.gif',
          'https://media.giphy.com/media/SggILpMXO7Xt6/giphy.gif','https://media.giphy.com/media/KHJw9NRFDMom487qyo/giphy.gif'
        ])),
      ),
    ),
  );
}

class Carousel extends StatelessWidget {
  const Carousel({super.key, required this.contentUrls});

  final List<String> contentUrls;

  @override
  Widget build(BuildContext context) {
    return Consumer(
      builder: (_, notifier, __) =>
          CarouselSlider(
              key: key,
              options: CarouselOptions(
                height: 300.0,
                onPageChanged: (index, _) {
                  Provider.of<CarouselNotifier>(context, listen: false)
                      .setIndex(index);
                },
              ),
              items: contentUrls
                  .map((e) =>
                  Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Container(
                      color: Colors.blue,
                      // display images from urls etc
                      child: Column(
                        children: [
                          Expanded(
                              flex: 3,
                              child: Center(child: Image.network(e))),
                          Expanded(child: Text('Page index ${contentUrls.indexOf(e)}'))
                        ],
                      ),
                    ),
                  ))
                  .toList()),
    );
  }
}

class CarouselNotifier extends ChangeNotifier {
  int activePage = 0;

  setIndex(int index) {
    activePage = index;
    notifyListeners();
  }
}

相关问题