如何在 Flutter 中的另一个全宽屏幕之上创建一个 1/3 宽度的屏幕?

How to create a screen of 1/3 width on top of another screen of full width in Flutter?

点击应用栏中的过滤器图标,我应该在当前全宽屏幕的顶部显示一个 1/3 宽度的过滤器屏幕。请问在 Flutter 中如何做到这一点?

三种可能:

  1. 使用抽屉 https://flutter.dev/docs/cookbook/design/drawer

这正是为了满足您的需求而设计的。使用脚手架

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    home: MyApp(),
  ));
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool showOverlay = false;
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("app bar")),
      drawer: Drawer(),
      body: Center(
        child: Text("Test"),
      ),
    );
  }
}

  1. 叠加条目 https://api.flutter.dev/flutter/widgets/OverlayEntry-class.html

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    home: MyApp(),
  ));
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  OverlayEntry? overlay;
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text("app bar")),
        floatingActionButton: FloatingActionButton(
          child: Icon(Icons.add),
          onPressed: () {
            final _overlay = _createOverlayEntry(context);
            Overlay.of(context)!.insert(_overlay);
            setState(() {
              overlay = _overlay;
            });
          },
        ),
        body: Center(
          child: Text("Test"),
        ));
  }

  OverlayEntry _createOverlayEntry(
    BuildContext context,
  ) {
    return OverlayEntry(
      builder: (context) => Stack(
        children: [
          Positioned(
  width: MediaQuery.of(context).size.width * (1.0 / 3.0),
        height: MediaQuery.of(context).size.height,
   top: 0,
        left: 0,
            child: Container(
              color: Colors.red,
              child: Center(
                child: ElevatedButton(
                  child: Text("close"),
                  onPressed: () {
                    // close overlay
                    overlay?.remove();
                  },
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

  1. 简单堆栈 https://api.flutter.dev/flutter/widgets/Stack-class.html
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MaterialApp(
        home: MyApp(),
      ));
    }
    
    class MyApp extends StatefulWidget {
      @override
      _MyAppState createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      bool showOverlay = false;
      @override
      void initState() {
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return Stack(
          children: [
            Scaffold(
              appBar: AppBar(title: Text("app bar")),
              floatingActionButton: FloatingActionButton(
                child: Icon(Icons.add),
                onPressed: () {
                  setState(() {
                    showOverlay = true;
                  });
                },
              ),
              body: Center(
                child: Text("Test"),
              ),
            ),
            if (showOverlay)
              Positioned(
      width: MediaQuery.of(context).size.width * (1.0 / 3.0),
            height: MediaQuery.of(context).size.height,
       top: 0,
            left: 0,
                child: Container(
                  color: Colors.red,
                  child: Center(
                    child: ElevatedButton(
                      child: Text("close"),
                      onPressed: () {
                        setState(() {
                          showOverlay = false;
                        });
                      },
                    ),
                  ),
                ),
              ),
          ],
        );
      }
    }