【问题标题】:Flutter switch between fragments by supporting back to previous fragmentFlutter 通过支持返回上一个片段在片段之间切换
【发布时间】:2019-05-20 14:59:16
【问题描述】:

this link in SF 中,@martinseal1987 向我们展示了如何将分离的小部件链接与 android 片段一起使用。

我在我的项目中实现了这个解决方案,在运行项目之后,我没有任何问题将第一个小部件显示为 Fragment,但是当我按下返回按钮时,我的屏幕变黑并且无法返回到以前的小部件一个片段

我认为应该是这样的:

问题navigateBackcustomPop 方法上,我可以通过按按钮附加片段

import 'package:flutter/material.dart';

void main()
{
  runApp(MaterialApp(
    title: 'AndroidMonks',
    home: Scaffold(
      appBar: AppBar(
        title: Text('Androidmonks'),
        backgroundColor: Colors.orangeAccent,
      ),
      body: Home(),
    ),
  ));
}

class Home extends StatefulWidget {
  Home({
    Key key,
  }) : super(key: key);

  @override
  State<Home> createState()=>_Home();
}

class _Home extends State<Home> {
  String title = "Title";
  int _currentIndex = 0;
  final List<int> _backstack = [0];

  @override
  Widget build(BuildContext context) {
    navigateTo(_currentIndex);
    //each fragment is just a widget which we pass the navigate function
    List<Widget> _fragments =[Fragment1(),Fragment2(),Fragment3()];
    //will pop scope catches the back button presses
    return WillPopScope(
      onWillPop: () {
        customPop(context);
      },
      child: Scaffold(
        body: Column(
          children: <Widget>[
            RaisedButton(
              child:Text('PRESS'),
              onPressed: (){
                _currentIndex++;
                navigateTo(_currentIndex);
              },
            ),
            Expanded(
              child: _fragments[_currentIndex],
            ),
          ],
        ),
      ),
    );
  }


  void navigateTo(int index) {
    _backstack.add(index);
    setState(() {
      _currentIndex = index;
    });

    _setTitle('$index');
  }

  void navigateBack(int index) {
    setState(() {
      _currentIndex = index;
    });

    _setTitle('$index');
  }

  customPop(BuildContext context) {
    if (_backstack.length - 1  > 0) {
      navigateBack(_backstack[_backstack.length - 1]);
    } else {
      _backstack.removeAt(_backstack.length - 1);
      Navigator.pop(context);
    }
  }
  //this method could be called by the navigate and navigate back methods
  _setTitle(String appBarTitle) {
    setState(() {
      title = appBarTitle;
    });
  }
}

class Fragment2 extends StatefulWidget {
  @override
  State<Fragment2> createState() => _Fragment2();
}

class _Fragment2 extends State<Fragment2> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: RaisedButton(
          child: Text("_Fragment2"),
          onPressed: (){
          }),
    );
  }
}


class Fragment1 extends StatefulWidget {
  @override
  State<Fragment1> createState() => _Fragment1();
}

class _Fragment1 extends State<Fragment1> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text("_Fragment1"),
    );
  }
}


class Fragment3 extends StatefulWidget {
  @override
  State<Fragment3> createState() => _Fragment3();
}

class _Fragment3 extends State<Fragment3> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text("_Fragment3"),
    );
  }
}

【问题讨论】:

标签: flutter flutter-layout


【解决方案1】:

我在您的代码中修复了一些逻辑,请仔细检查更改,如果您有任何问题,请不要犹豫,这是工作代码

import 'package:flutter/material.dart';

void main()
{
  runApp(MaterialApp(
    title: 'AndroidMonks',
    home: Scaffold(
      appBar: AppBar(
        title: Text('Androidmonks'),
        backgroundColor: Colors.orangeAccent,
      ),
      body: Home(),
    ),
  ));
}

class Home extends StatefulWidget {
  Home({
    Key key,
  }) : super(key: key);

  @override
  State<Home> createState()=>_Home();
}

class _Home extends State<Home> {
  String title = "Title";
  List<Widget> _fragments =[Fragment1(),Fragment2(),Fragment3()];
  int _currentIndex = 0;
  final List<int> _backstack = [0];

  @override
  Widget build(BuildContext context) {
    //navigateTo(_currentIndex);
    //each fragment is just a widget which we pass the navigate function

    //will pop scope catches the back button presses
    return WillPopScope(
      onWillPop: () {
        return customPop(context);
      },
      child: Scaffold(
        body: Column(
          children: <Widget>[
            RaisedButton(
              child:Text('PRESS'),
              onPressed: (){
                _currentIndex++;
                navigateTo(_currentIndex);
              },
            ),
            Expanded(
              child: _fragments[_currentIndex],
            ),
          ],
        ),
      ),
    );
  }


  void navigateTo(int index) {
    _backstack.add(index);
    setState(() {
      _currentIndex = index;
    });

    _setTitle('$index');
  }

  void navigateBack(int index) {
    setState(() {
      _currentIndex = index;
    });

    _setTitle('$index');
  }

  Future<bool> customPop(BuildContext context) {
    print("CustomPop is called");
    print("_backstack = $_backstack");
    if (_backstack.length   > 1) {
      _backstack.removeAt(_backstack.length - 1);
      navigateBack(_backstack[_backstack.length - 1]);

      return Future.value(false);
    } else {

      return Future.value(true);
    }
  }
  //this method could be called by the navigate and navigate back methods
  _setTitle(String appBarTitle) {
    setState(() {
      title = appBarTitle;
    });
  }
}

class Fragment2 extends StatefulWidget {
  @override
  State<Fragment2> createState() => _Fragment2();
}

class _Fragment2 extends State<Fragment2> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: RaisedButton(
          child: Text("_Fragment2"),
          onPressed: (){
          }),
    );
  }
}


class Fragment1 extends StatefulWidget {
  @override
  State<Fragment1> createState() => _Fragment1();
}

class _Fragment1 extends State<Fragment1> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text("_Fragment1"),
    );
  }
}


class Fragment3 extends StatefulWidget {
  @override
  State<Fragment3> createState() => _Fragment3();
}

class _Fragment3 extends State<Fragment3> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text("_Fragment3"),
    );
  }
}

【讨论】:

  • 从 backStack 按下 onback 似乎支持,一步一步不正确
  • @DolDurma 请检查添加的 gif 图像代码是否正常工作,请确保您复制了准确​​的代码。
  • 你能测试一下这段代码吗:RaisedButton(child: Text('PRESS'), onPressed: () {var rnd = Random();_currentIndex = rnd.nextInt(3);navigateTo(_currentIndex);},),
  • @DolDurma 我试过了,没有明显问题,如果发现有问题请告诉我。
  • 假设您了解未来的概念,它会创建一个以 false 完成的未来,因此,它否决不弹出当前的 ModalRoute
【解决方案2】:

您可以使用LocalHistoryRoute.of(context).addLocalHistoryEntryNavigator.pop() 实现这种类型的导航。

【讨论】:

  • 谢谢,但我不确定这不是我想要做的,我只想将屏幕中心的小部件替换为body,而不是更改所有屏幕,例如活动
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-08
  • 1970-01-01
相关资源
最近更新 更多