首页 > 解决方案 > 尝试在颤动中打开抽屉时出现意外的空值

问题描述

我试图打开抽屉,它给了我以下错误:

======== Exception caught by gesture ===============================================================
The following TypeErrorImpl was thrown while handling a gesture:
Unexpected null value.

When the exception was thrown, this was the stack: 
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 236:49      throw_
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 518:63  nullCheck
packages/l7/screens/main/view_model/main_view_model.dart 15:36                    openOrCloseDrawer
packages/l7/screens/main/view/components/header.dart 35:42                        <fn>
packages/flutter/src/material/ink_well.dart 989:21                                [_handleTap]
...
Handler: "onTap"
Recognizer: TapGestureRecognizer#ae119
  debugOwner: GestureDetector
  state: possible
  won arena
  finalPosition: Offset(35.8, 49.7)
  finalLocalPosition: Offset(15.8, 12.9)
  button: 1
  sent tap down
====================================================================================================

下面的方法是openOrCloseDrawer()

  void openOrCloseDrawer() {
    if (_scaffoldKey.currentState!.isDrawerOpen) {
      _scaffoldKey.currentState!.openEndDrawer();
      setState(ViewState.Idle);
    } else {
      _scaffoldKey.currentState!.openDrawer();
      setState(ViewState.Idle);
    }
  }

与以下有关ViewModel

import 'package:flutter/material.dart';
import 'package:l7/enums/ScreenState.dart';
import 'package:l7/screens/BaseViewModel.dart';

class MainViewModel extends BaseViewModel {
  int _selectedIndex = 0;
  GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

  int get selectedIndex => _selectedIndex;
  List<String> get menuItems =>
      ["Cases", "Services", "About Us", "Careers", "Blog", "Contact"];
  GlobalKey<ScaffoldState> get scaffoldkey => _scaffoldKey;

  void openOrCloseDrawer() {
    if (_scaffoldKey.currentState!.isDrawerOpen) {
      _scaffoldKey.currentState!.openEndDrawer();
      setState(ViewState.Idle);
    } else {
      _scaffoldKey.currentState!.openDrawer();
      setState(ViewState.Idle);
    }
  }

  void setMenuIndex(int index) {
    _selectedIndex = index;
    setState(ViewState.Idle);
  }
}

这是以下内容BaseViewModel

import 'package:flutter/widgets.dart';
import 'package:l7/enums/ScreenState.dart';
import 'package:l7/utils/context_extentions.dart';

class BaseViewModel extends ChangeNotifier {
  ViewState _state = ViewState.Idle;

  ViewState get state => _state;

  SwitchState _switchState = SwitchState.CLOSE;

  SwitchState get switchState => _switchState;

  void setState(ViewState viewState) {
    _state = viewState;
    notifyListeners();
  }

  void switchLanguage(bool state, BuildContext context) async {
    state == true
        ? _switchState = SwitchState.OPEN
        : _switchState = SwitchState.CLOSE;

    notifyListeners();

    if (context.locale == const Locale('ar', 'EG')) {
      context.setLocale(const Locale('en', 'US'));
    } else {
      context.setLocale(const Locale('ar', 'EG'));
    }
  }
}

这是以下Drawer组件:

import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:l7/screens/BaseScreen.dart';
import 'package:l7/screens/main/view_model/main_view_model.dart';
import 'package:l7/utils/constants.dart';


class SideMenu extends StatelessWidget {
  // final MenuController _controller = Get.put(MenuController());

  @override
  Widget build(BuildContext context) {
    return BaseScreen<MainViewModel>(
      onModelReady: (mainViewModel){},
      builder: (context, viewModel, _){
        return Drawer(
          child: Container(
            color: kDarkBlackColor,
            child: ListView(
              children: [
                DrawerHeader(
                  child: Padding(
                    padding: const EdgeInsets.symmetric(
                        horizontal: kDefaultPadding * 3.5),
                    child: SvgPicture.asset("assets/icons/logo.svg"),
                  ),
                ),
                ...List.generate(
                  viewModel.menuItems.length,
                      (index) => DrawerItem(
                    isActive: index == viewModel.selectedIndex,
                    title: viewModel.menuItems[index],
                    press: () {
                      viewModel.setMenuIndex(index);
                    },
                  ),
                ),
              ],
            ),
          ),
        );
      },
    );
  }
}

class DrawerItem extends StatelessWidget {
  final String? title;
  final bool? isActive;
  final VoidCallback? press;

  const DrawerItem({
    Key? key,
    @required this.title,
    @required this.isActive,
    @required this.press,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: ListTile(
        contentPadding: EdgeInsets.symmetric(horizontal: kDefaultPadding),
        selected: isActive!,
        selectedTileColor: kPrimaryColor,
        onTap: press,
        title: Text(
          title!,
          style: TextStyle(color: Colors.white),
        ),
      ),
    );
  }
}

这是包含抽屉的标题小部件:

import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:l7/screens/BaseScreen.dart';
import 'package:l7/screens/main/view/components/web_menu.dart';
import 'package:l7/screens/main/view_model/main_view_model.dart';
import 'package:l7/services/responsive.dart';
import 'package:l7/utils/constants.dart';
import 'package:l7/utils/texts.dart';

import 'header_right_side.dart';

class Header extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return BaseScreen<MainViewModel>(
      onModelReady: (mainViewModel) {},
      builder: (context, viewModel, _) {
        return SafeArea(
          child: Column(
            children: [
              Column(
                children: [
                  Row(
                    children: [
                      if (!Responsive.isDesktop(context))
                        IconButton(
                          icon: Icon(
                            Icons.menu,
                            color: kBlackBlue,
                          ),
                          onPressed: () {
                            viewModel.openOrCloseDrawer();
                          },
                        ),
                      Image.asset("assets/images/l7_image.png", height: MediaQuery.of(context).size.height * 0.15,),
                      Spacer(),
                      if (Responsive.isDesktop(context)) WebMenu(),
                      Spacer(),
                      HeaderRightSide(),
                    ],
                  ),
                  // SizedBox(height: kDefaultPadding * 2),
                  Container(
                    width: double.infinity,
                    height: MediaQuery.of(context).size.height * 0.27,
                    decoration: BoxDecoration(
                        image: DecorationImage(image: AssetImage('assets/images/blog_bg.png'), fit: BoxFit.cover)
                    ),
                    child: Row(
                      children: [
                        Expanded(
                          child: Column(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: [
                              headLine30TitleText(
                                tr("Welcome to Our Blog"),
                                context,
                              ),
                              Padding(
                                padding:
                                const EdgeInsets.symmetric(vertical: kDefaultPadding),
                                child: Text(
                                  "Stay updated with the newest design and development stories, case studies, \nand insights shared by DesignDK Team.",
                                  textAlign: TextAlign.center,
                                  style: TextStyle(
                                    color: Colors.white,
                                    fontFamily: 'Raleway',
                                    height: 1.5,
                                  ),
                                ),
                              ),
                              FittedBox(
                                child: TextButton(
                                  onPressed: () {},
                                  child: Row(
                                    children: [
                                      Text(
                                        "Learn More",
                                        style: TextStyle(
                                          fontWeight: FontWeight.bold,
                                          color: Colors.white,
                                        ),
                                      ),
                                      SizedBox(width: kDefaultPadding / 2),
                                      Icon(
                                        Icons.arrow_forward,
                                        color: Colors.white,
                                      ),
                                    ],
                                  ),
                                ),
                              ),
                            ],
                          ),
                        ),
                        IconButton(onPressed: (){}, icon: Icon(Icons.keyboard_arrow_right, color: Colors.white,))
                      ],
                    ),
                  ),
                  if (Responsive.isDesktop(context))
                    SizedBox(height: kDefaultPadding),
                ],
              )
            ],
          ),
        );
      },
    );
  }
}

我希望有人可以提供帮助,如果有任何遗漏的细节或代码,请告诉我。:)

标签: flutterdart

解决方案


小部件中以下行代码中的解决方案Header

代替:

viewModel.openOrCloseDrawer();

添加这一行:

Scaffold.of(context).openDrawer();

推荐阅读