Flutter Navigator-从页面堆栈交换页面

时间:2020-10-29 20:17:14

标签: flutter

我的情况有点乏味。我将2页推入导航器

A-B

B被推到最后。

出于某些原因。我不想弹出B从B导航到A。我想替换/交换它们。原因是由于状态。我想保留A和B页面的状态,因为有些小部件的构建成本非常高(Unity视图小部件)。如何通过B使用Navigator,以便在不破坏页面的情况下可以将B与A交换?

这是流程:

  • A将打开为默认页面。

  • B被按下

    Navigator.of(context).pushNamed();

    页面堆栈是A-B

  • 我想从B导航到A,同时仍然保持B页面有效。

  • -经过一些神奇的操作后,我很想念-

  • 页面堆栈为B-A。用户看到页面A。没有页面被破坏。他们被交换了。

在Flutter中有没有办法做到这一点?

3 个答案:

答案 0 :(得分:3)

您可以通过简单的方式使用PageView并按以下方式设置配置:

PageController _pagerController = PageController(keepPage: true);

PageView(
      physics: NeverScrollableScrollPhysics(),
      controller: _pagerController,
      children: [
         Page_A(),
         Page_B(),
      ],
),

在页面之间切换:

goNextPage() {
  _pagerController.animateToPage(
    currentPage + 1,
    duration: Duration(milliseconds: 500),
    curve: Curves.ease,
  );
}

goPrevPage() {
  _pagerController.animateToPage(
    currentPage - 1,
    duration: Duration(milliseconds: 500),
    curve: Curves.ease,
  );
}

我希望它对您有用。

答案 1 :(得分:0)

也许您正在寻找IndexedStack。它在类似电视频道的小部件之间切换。更改时不会重新构建该小部件。

根据您的需求,切换带有动画的页面,AnimatedSwitcher似乎与您想要的最接近,除了它确实重建了窗口小部件。因此,我认为IndexedStack是您想要的一个很好的开始。

您还可以参考animated_indexed_stack.dart

中提到的AnimatedSwitcher with IndexedStackthis thread

答案 2 :(得分:-1)

PageView,ListView和GridView构建器是为大量对象设计的。并在滚动时重建

列或行保存其所有子代版本。

您可以尝试:

SingleChildScrollView(NeverScrollable)->行-> A(相等的屏幕大小)和B(相同)

而不是设置动画或跳转至:

对于A偏移0和B偏移屏幕宽度。

我尝试过,工作正常

enter image description here

    
///
class AtoBExample extends StatefulWidget {
  @override
  _AtoBExampleState createState() => _AtoBExampleState();
}

class _AtoBExampleState extends State<AtoBExample> {
  ScrollController scrollController = ScrollController();

  _toB() {
    // !!! Forward or any operations animations in here
    // e.g animate A's opacity 1 to 0 and wait finish

    scrollController.jumpTo(MediaQuery.of(context).size.width);

    // And animate B's opacity 0 to 1
  }

  _toA() {
    // !!! Forward or any operations animations in here
    // e.g animate B's opacity 1 to 0 and wait finish

    scrollController.jumpTo(0);

    // And animate A's opacity 0 to 1
  }

  @override
  Widget build(BuildContext context) {
    var size = MediaQuery.of(context).size;
    return Scaffold(
      body: SingleChildScrollView(
        controller: scrollController,
        scrollDirection: Axis.horizontal,
        physics: const NeverScrollableScrollPhysics(),
        child: Row(
          children: [
            // A
            Builder(
              builder: (c) {
                print('GREEN BUILD');
                return InkWell(
                  onTap: (){
                    print('TO B');
                    _toB();
                  },
                  child: Container(
                    width: size.width,
                    height: size.height,
                    color: Colors.green,
                  ),
                );
              },
            ),
            Builder(
              builder: (c) {
                print('RED BUILD');
                return InkWell(
                  onTap: (){
                    print('TO A');
                    _toA();
                  },
                  child: Container(
                    width: size.width,
                    height: size.height,
                    color: Colors.red,
                  ),
                );
              },
            )
          ],
        ),
      ),
    );
  }
}