【问题标题】:ScrollController attached to multiple scroll views. flutterScrollController 附加到多个滚动视图。扑
【发布时间】:2021-08-12 17:33:18
【问题描述】:

我尝试使用 GetX 重建 Instagram 故事。我总是收到这个问题。 谁能帮我解决这个问题?

ScrollController 附加到多个滚动视图。 'package:flutter/src/widgets/scroll_controller.dart': 断言失败:第 109 行 pos 12:'_positions.length == 1'

我尝试使用 GetX 重建 Instagram 故事。我总是收到这个问题。 谁能帮我解决这个问题?

ScrollController 附加到多个滚动视图。 'package:flutter/src/widgets/scroll_controller.dart': 断言失败:第 109 行 pos 12:'_positions.length == 1'

import 'package:flamingo/Business_Logic/GetXControllers/Pages_Controllers/Stories_Controller.dart';
import 'package:flamingo/Data/DataProviders/StoriesList.dart';
import 'package:flamingo/Data/Models/All_Models.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

class Stories extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GetBuilder<StoriesController>(
      init: StoriesController(),
      builder: (storiesCtrl) {
        return Scaffold(
          backgroundColor: Colors.black,
          body: GestureDetector(
            onTapDown: (details) => storiesCtrl.onTapDown(
                details, story[storiesCtrl.currentIndex.value]),
            child: Stack(
              children: <Widget>[
                PageView.builder(
                  controller: storiesCtrl.pageC,
                  physics: NeverScrollableScrollPhysics(),
                  itemBuilder: (context, i) {
                    final StoryModel s = story[i];
                    switch (s.media) {
                      case MediaType.image:
                        return Image.network(
                          s.image,
                          fit: BoxFit.cover,
                        );
                    }
                    return const SizedBox.shrink();
                  },
                ),
                Positioned(
                  top: 15.0,
                  left: 10.0,
                  right: 10.0,
                  child: Row(
                    children: story
                        .asMap()
                        .map((i, e) {
                          return MapEntry(
                              i,
                              Flexible(
                                child: Padding(
                                  padding: const EdgeInsets.symmetric(
                                      horizontal: 1.5),
                                  child: LayoutBuilder(
                                      builder: (context, constraints) {
                                    return Stack(
                                      children: <Widget>[
                                        _buildContainer(
                                          double.infinity,
                                          i < storiesCtrl.currentIndex.value
                                              ? Colors.white
                                              : Colors.white.withOpacity(0.5),
                                        ),
                                        i == storiesCtrl.currentIndex.value
                                            ? AnimatedBuilder(
                                                animation: storiesCtrl.animC,
                                                builder: (context, child) {
                                                  return _buildContainer(
                                                    constraints.maxWidth *
                                                        storiesCtrl.animC.value,
                                                    Colors.white,
                                                  );
                                                },
                                              )
                                            : const SizedBox.shrink(),
                                      ],
                                    );
                                  }),
                                ),
                              ));
                        })
                        .values
                        .toList(),
                  ),
                ),
              ],
            ),
          ),
        );
      },
    );
  }

  Container _buildContainer(double width, Color color) {
    return Container(
      height: 5.0,
      width: width,
      decoration: BoxDecoration(
        color: color,
        border: Border.all(
          color: Colors.black26,
          width: 0.8,
        ),
        borderRadius: BorderRadius.circular(3.0),
      ),
    );
  }
}


import 'package:flamingo/Data/Models/StoryModel.dart';
import 'package:flamingo/Utils/AllUtils.dart';
import 'package:flutter/animation.dart';
import 'package:flutter/material.dart';
import 'package:flamingo/Data/DataProviders/StoriesList.dart';
import 'package:get/get.dart';

class StoriesController extends GetxController
    with SingleGetTickerProviderMixin {
  List<StoryModel> stories;
  AnimationController animC;
  var pageC;
  var currentIndex = 0.obs;

  @override
  void onInit() {
    stories = story;
    super.onInit();
    pageC = PageController();
    animC = AnimationController(vsync: this);
    final StoryModel firstStory = stories.first;
    loadStory(story: firstStory, animateToPage: false);

    animC.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        animC.stop();
        animC.reset();

        if (currentIndex.value + 1 < stories.length) {
          currentIndex.value += 1;
          loadStory(story: stories[currentIndex.value]);
          update();
        } else {
          currentIndex.value = 0;
          loadStory(story: stories[currentIndex.value]);
          update();
        }
      }
    });
  }

  void onTapDown(TapDownDetails details, StoryModel s) {
    final double dx = details.globalPosition.dx;
    if (dx < GlobalSize.screenWidth / 3) {
      if (currentIndex.value - 1 >= 0) {
        currentIndex.value -= 1;
        loadStory(story: story[currentIndex.value]);
        update();
      }
    } else if (dx > 2 * GlobalSize.screenWidth / 3) {
      if (currentIndex.value + 1 < story.length) {
        currentIndex.value += 1;
        loadStory(story: story[currentIndex.value]);
      } else {
        currentIndex.value = 0;
        loadStory(story: story[currentIndex.value]);
      }
    }
  }

  void loadStory({StoryModel story, bool animateToPage = true}) {
    animC.stop();
    animC.reset();

    switch (story.media) {
      case MediaType.image:
        animC.duration = story.duration;
        animC.forward();
        break;
    }
    if (animateToPage) {
      pageC.animateToPage(
        currentIndex.value,
        duration: const Duration(microseconds: 1),
        curve: Curves.easeInOut,
      );
    }
  }

  @override
  void onClose() {
    pageC.value.dispose();
    animC.dispose();
    super.onClose();
  }
}

【问题讨论】:

    标签: flutter dart hybrid-mobile-app mobile-application


    【解决方案1】:

    好的,我遇到了同样的问题,但对我来说,它实际上与我使用控制器的代码无关。如果您从多个页面访问同一个控制器,通常会出现此问题。但是,如果您在路由器堆栈上有同一页面的多个实例,也会发生这种情况。在我的情况下,我在应用程序的其他地方使用Get.to() 导航回我的主页,该主页在堆栈上创建了我的主页的另一个实例,因此出现了多个控制器错误。

    所以为了解决这个问题,我将Get.to() 更改为Get.offAll()。如果您使用命名路由,请将Get.toNamed() 切换为Get.offAllNamed()

    如果您在执行此操作后遇到错误,表明您的控制器已找不到,请在您的绑定中,在使用 Get.put() 实例化您的控制器时设置 permanent: trueGet.put(Home(), permanent: true);

    查看您的代码,错误似乎不是来自两次使用同一个控制器,而是当您从应用程序中的某个位置路由回此页面时可能会发生错误。花了我很长时间才弄清楚,但实际上,当您将相同的页面添加到堆栈中时,Flutter 会创建另一个“共享”控制器实例,因此您必须在导航时从堆栈中删除原始页面。

    如果有人在导航中遇到此错误并且没有使用 GetX 进行状态管理,请使用 Navigation.pushNamedAndRemoveUntil() 导航回带有控制器的页面。

    【讨论】:

      猜你喜欢
      • 2019-02-09
      • 2019-02-28
      • 1970-01-01
      • 2019-05-18
      • 2019-02-06
      • 2019-07-30
      • 2019-02-17
      • 1970-01-01
      • 2020-01-27
      相关资源
      最近更新 更多