将屏幕移到导航器顶部

时间:2019-06-22 22:05:42

标签: flutter dart

我已经搜索了一段时间,但找不到任何选择来执行此操作。这有可能吗?

在以下情况下

Page1 > Page2 > Page3 > Page4

可以从Page4中导航到Page2,而无需创建新的Page2吗?

所需结果:

Page1 >??empty?? > Page3 > Page4 > Page2

正常结果:

Page1 > Page2 > Page3 > Page4 > different Page2

这甚至有可能扑扑吗?

2 个答案:

答案 0 :(得分:2)

是的,您可以从第4页返回到第2页

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";

    private String RxuserId;
    public ArrayList<String> mToken;
    MutableLiveData<String> data = new MutableLiveData<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        RxuserId = intent.getStringExtra("Id");

        mToken = new ArrayList<>();

        if(RxuserId != null){            
            database.getReference().child("users").child(RxuserId).addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    data.setValue(dataSnapshot.child("fcm token").getValue().toString());
                }

                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {

                }
            });   
        }

        data.observe(this, new Observer<String>() {
            @Override
            public void onChanged(String s) {
                mToken.add(s);
                Toast.makeText(getApplicationContext(), "REQUIRED TOKRN  " + s,Toast.LENGTH_LONG).show();

                Log.d(TAG,"REQUIRED TOKRN  " + string);
                Log.d(TAG,"REQUIRED TOKRN  " + mToken.size())
            }
        });
    }
}

答案 1 :(得分:0)

好一会儿,我找到了答案。

理想的答案应该具备一些先决条件

  • 推到顶部时应保持其状态
  • 应该可以从应用程序中的任何位置推送
  • 应该是同一屏幕[不是重建的屏幕]
  • 它应该能够进行自定义过渡
  • 它不应该以任何方式卸载[状态丢失]

最重要的一个

  • 它应该能够转到任何导航器的顶部,但不能停留在导航器树中。

解决方案

应用程序根目录中的一个Backdrop小部件

为此,我发现了this个带有背景的中等文章。

出于个人用途,我删除了滑动功能,并添加了后退按钮处理程序(因此它充当导航器中的屏幕)。

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

const _kFlingVelocity = 2.0;

class Backdrop extends StatefulWidget {
  final Widget frontLayer;
  final Widget backLayer;
  final ValueNotifier<bool> panelVisible;

  Backdrop(
      {@required this.frontLayer, @required this.backLayer, this.panelVisible})
      : assert(frontLayer != null),
        assert(backLayer != null);

  @override
  createState() => _BackdropState();
}

class _BackdropState extends State<Backdrop>
    with SingleTickerProviderStateMixin {
  final _backdropKey = GlobalKey(debugLabel: 'Backdrop');
  AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: Duration(milliseconds: 300),
      value: (widget.panelVisible?.value ?? true) ? 1.0 : 0.0,
      vsync: this,
    );

    widget.panelVisible?.addListener(_subscribeToValueNotifier);
    if (widget.panelVisible != null) {
      _controller.addStatusListener((status) {
        if (status == AnimationStatus.completed)
          widget.panelVisible.value = true;
        else if (status == AnimationStatus.dismissed)
          widget.panelVisible.value = false;
      });
    }
  }

  void _subscribeToValueNotifier() {
    if (widget.panelVisible.value != _backdropPanelVisible)
      _toggleBackdropPanelVisibility();
  }

  @override
  void didUpdateWidget(Backdrop oldWidget) {
    super.didUpdateWidget(oldWidget);
    oldWidget.panelVisible?.removeListener(_subscribeToValueNotifier);
    widget.panelVisible?.addListener(_subscribeToValueNotifier);
  }

  @override
  void dispose() {
    _controller.dispose();
    widget.panelVisible?.dispose();
    super.dispose();
  }

  bool get _backdropPanelVisible =>
      _controller.status == AnimationStatus.completed ||
      _controller.status == AnimationStatus.forward;

  void _toggleBackdropPanelVisibility() => _controller.fling(
      velocity: _backdropPanelVisible ? -_kFlingVelocity : _kFlingVelocity);

  Future<bool> _onWillPop() async {
    if (widget.panelVisible.value) {
      widget.panelVisible.value = false;
      return false;
    }

    return true;
  }

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(builder: (context, constraints) {
      final panelDetailsPosition = Tween<Offset>(
        begin: Offset(0.0, 1.0),
        end: Offset(0.0, 0.0),
      ).animate(_controller.view);

      return WillPopScope(
          onWillPop: _onWillPop,
          child: Container(
            key: _backdropKey,
            child: Stack(
              children: <Widget>[
                widget.backLayer,
                SlideTransition(
                    position: panelDetailsPosition, child: widget.frontLayer),
              ],
            ),
          ));
    });
  }
}

我在一家全球商店中拥有final frontPanelVisible = ValueNotifier<bool>(false);,因此我可以从应用程序中的任何位置调用它,并“推动”这个瞬移的魔术屏幕。

在我应用程序的主窗口小部件中,我有类似的内容

class Panels extends StatelessWidget {
  final frontPanelVisible = ValueNotifier<bool>(false);

  @override
  Widget build(BuildContext context) {
    return Backdrop(
      frontLayer: MainAppScreen(),
      backLayer: MagicalScreen(),
      panelVisible: frontPanelVisible,
    );
  }
}

跳到层次结构中是很神奇的,而且,它节省了大量资源[因为不是由15个具有相同内容的屏幕组成,我只有1个屏幕],也许可以稍加修改就可以在其中有一个嵌套的导航器。可能性是无限的。