如何仅在 SplitView 中的特定容器中单击而不是在整个页面中显示下一页(无状态小部件)

How to show next page (Stateless widget) on click only in specific Container in SplitView, not all over the page

我有 TestApp,其中有带 2 个水平容器的 SplitView。通过单击左侧第一个容器中的按钮(蓝色),我想显示新页面(DetailPage 小部件)但不是在整个页面中,而是仅在第一个容器中。现在它显示在整个屏幕上。最好的方法是什么?

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

void main() {
  runApp(MaterialApp(
    title: 'Test',
    home: TestApp(),
  ));
}

class TestApp extends StatelessWidget {
  const TestApp({Key key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: SplitView(
        children: [
          Container(
            color: Colors.blue,
            child: ElevatedButton(
                onPressed: () {
                  Navigator.push(context,
                      MaterialPageRoute(builder: (context) => DetailPage()));
                },
                child: const Text('CLICK')),
          ),
          Container(color: Colors.yellow),
        ],
        viewMode: SplitViewMode.Horizontal,
        indicator: SplitIndicator(viewMode: SplitViewMode.Horizontal),
        activeIndicator: SplitIndicator(
          viewMode: SplitViewMode.Horizontal,
          isActive: true,
        ),
        controller: SplitViewController(limits: [null, WeightLimit(max: 1)]),
      ),
    );
  }
}

class DetailPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text('')), body: Container(color: Colors.red));
  }
}

当您使用 Navigator.push 路由到新页面并创建新状态时。我认为您应该改用 showGeneralDialog

showGeneralDialog(
                  context: context,
                  pageBuilder: (BuildContext context,
                      Animation<double> animation, Animation<double> pagebuilder) {
                    return Align(
                      alignment: Alignment.centerLeft,
                      child: Card(
                          child: Container(
                              alignment: Alignment.topLeft,
                              color: Colors.amber,
 //show half the screen width
                              width: MediaQuery.of(context).size.width / 2,
                              child: IconButton(
                                  icon: const Icon(Icons.cancel),
                                  onPressed: () {
                                    Navigator.pop(context);
                                  }))),
                    );
                  });

尝试在容器中创建新的导航器:

  GlobalKey<NavigatorState> _navKey = GlobalKey();

      home: SplitView(
        children: [
          Container(
            child: Navigator(
        key: _navKey,
        onGenerateRoute: (_) => MaterialPageRoute<dynamic>(
          builder: (_) {
return Container(
            color: Colors.blue,
            child: ElevatedButton(
                onPressed: () {
                  Navigator.push(context,
                      MaterialPageRoute(builder: (context) => DetailPage()));
                },
                child: const Text('CLICK')),
          );
},
        ),
      ),),
          

推送新页面时,您将覆盖旧页面,这意味着新页面不会有 spiltView,最好的方法是更改​​ [=12] 中显示的小部件=] 像这样:

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

void main() {
  runApp(MaterialApp(
    title: 'Test',
    home: TestApp(),
  ));
}

class TestApp extends StatefulWidget { // I have already changed the widgte to stateful here
  const TestApp({Key? key}) : super(key: key);

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

class _TestAppState extends State<TestApp> {
  @override
  Widget build(BuildContext context) {
    bool Bool;
    return MaterialApp(
      home: SplitView(
        children: [
          if (Bool == false){
             Container(
              color: Colors.blue,
              child: ElevatedButton(
                  onPressed: () {
                    setState(() {
                      Bool = !Bool; // this the method for inverting the boolean, it just gives it the opposite value  
                    });
                  },
                  child: const Text('CLICK')),
            ),
          }
          else{
            DetailPage()
          },

          Container(color: Colors.yellow),
        ],
        viewMode: SplitViewMode.Horizontal,
        indicator: SplitIndicator(viewMode: SplitViewMode.Horizontal),
        activeIndicator: SplitIndicator(
          viewMode: SplitViewMode.Horizontal,
          isActive: true,
        ),
        controller: SplitViewController(limits: [null, WeightLimit(max: 1)]),
      ),
    );
  }
}

class DetailPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text('')), body: Container(color: Colors.red));
  }
}

上面我定义了一个名为 Boolbool,在呈现页面时它检查 Bool 是否为 false,在这种情况下它 returns 蓝色小部件,如果它是真的然后它 returns 红色的,当你点击按钮时它反转 bool 并更新页面。

请注意,要更新页面,您必须使用 setState 来重建小部件,要使用它,您必须使用 stateful 小部件,因为 stateless widget 是静态的并且无法更改。

我还没有测试代码,因为我没有 split_view 包,但你应该可以复制和粘贴它,如果有任何错误请告诉我。