通过支持返回到先前的片段,颤振片在片段之间切换

时间:2019-05-20 14:59:17

标签: flutter flutter-layout

在SF的this link中,@martinseal1987向我们展示了如何使用带有Android片段的分离的小部件链接。

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

我认为应该是这样的:

enter image description here

问题位于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"),
    );
  }
}

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

我已修复您代码中的某些逻辑,请仔细检查更改,如果您有任何疑问请不要犹豫,这是有效的代码

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"),
    );
  }
}

a