[Flutter] Switch 위젯 No Material Widget Found 에러

2023. 5. 7. 00:55Developers 공간 [Shorts]/Frontend

728x90
반응형
<분류>
A. 수단
- OS/Platform/Tool : Linux, Kubernetes(k8s), Docker, AWS
- Package Manager : node.js, yarn, brew, 
- Compiler/Transpillar : React, Nvcc, gcc/g++, Babel, Flutter

- Module Bundler  : React, Webpack, Parcel

B. 언어
- C/C++, python, Javacsript, Typescript, Go-Lang, CUDA, Dart, HTML/CSS

C. 라이브러리 및 프레임워크 및 SDK
- OpenCV, OpenCL, FastAPI, PyTorch, Tensorflow, Nsight

 


1. What? (현상)

Align(
  alignment : Alignment.centerRight,
  child:Container(
    height: 50,
    width: 50,
    child: Switch(
      value: viewModel.mapmode,
      activeColor: Colors.red,
      onChanged: viewModel.onSwitchPressed,
    ),
  ),
)

위와 같이 Switch를 구현하고 나니 아래와 같은 에러가 납니다.

══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY╞═══════════════════════════
The following assertion was thrown building _MaterialSwitch(dirty, state: _MaterialSwitchState#d54cd(tickers: tracking 4 tickers)):
No Material widget found.
_MaterialSwitch widgets require a Material widget ancestor.
In Material Design, most widgets are conceptually "printed" on a sheet of material.

In Flutter's material library, that material is represented by the Material widget.
It is the Material widget that renders ink splashes, for instance.
Because of this, many material library widgets require that there be a Material widget in the tree above them.

To introduce a Material widget, you can either directly include one, or use a widget that contains Material itself, such as a Card, Dialog, Drawer, or Scaffold.

The specific widget that could not find a Material ancestor was:
_MaterialSwitch
The ancestors of this widget were:

Switch
ConstrainedBox
Container
Align
Row

해결책을 찾아보고자 합니다.


2. Why? (원인)

MaterialApp이란 보통 우리는 대부분의 하위페이지와 구성요소를 최상단에서 담으려는 그릇정도로 알고 있습니다.

공식 페이지(https://api.flutter.dev/flutter/material/MaterialApp-class.html)에 따르면, 아래와 같습니다.

An application that uses Material Design.

A convenience widget that wraps a number of widgets that are commonly required for Material Design applications.

It builds upon a WidgetsApp by adding material-design specific functionality, such as AnimatedTheme and GridPaper.

The MaterialApp configures the top-level Navigator to search for routes 

즉, Material Design을 따르며, 우리가 아는 것처럼 수많은 위젯들을 감싸는 Wrapper입니다.

추가적으로 알 것은 WidgetApp을 상속해서 만들지만, AnimatedTheme나 GridPaper같은 Material 디자인 기능을 추가할 수 있다는 것입니다.

중요한 것은 Wrapper개념보다는 (Google이 지향하는) Material Design을 사용할 수 있게 해준다는 것이 핵심입니다.

 

그래서 어떤 위젯은 Material Widget으로 감싸지 않으면, No Material Widget Found라는 에러가 나는 것입니다.


3. How? (해결책)

보통의 해결책은 아래와 같이 Material자체를 가지고 있는 위젯자체로 구현하거나, 이 위젯들로 감싸주는 것으로 해결한다고 합니다.

  • Card Widget : 하나의 주제로 content를 만들 때
 Card(
    child: Column(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        const ListTile(
          leading: Icon(Icons.account_circle, size: 50),
          title: Text('Title Text'),
          subtitle: Text('Secondary Text'),
        ),
      ],
    ),
  ),
  • Dialog Widget : pop-up box를 만들 때
AlertDialog({
   Key key,
   Widget title,
   EdgeInsetsGeometry titlePadding,
   TextStyle titleTextStyle,
   Widget content,
   EdgeInsetsGeometry contentPadding:
       const EdgeInsets.fromLTRB(24.0, 20.0, 24.0, 24.0),
   TextStyle contentTextStyle,
   List<Widget> actions,
   Color backgroundColor,
   double elevation,
   String semanticLabel,
   ShapeBorder shape,
 });
  • Drawer : Sacffold의 일부로, 애니메이션이 포함되어있습니다.
Scaffold(
  drawer: Drawer(
      elevation: 20.0,
      child: ListView(
        padding: EdgeInsets.zero,
        children: <Widget>[
        ],
      )),
)
  • Scaffold Widget : Scaffold를 활용해서 감싸주기도 합니다.
Scaffold(
    appBar: AppBar(
      title: Text('Demo'),
    ),
    body: MyWidget() --> put your widget here
);

 

 

저는 아래와 같이 Card로 감싸주는 것으로 해결했습니다.

 Card(
    child: Align(
      alignment : Alignment.centerRight,
      child:Container(
        height: 50,
        width: 50,
        child: Switch(
          value: viewModel.mapmode,
          activeColor: Colors.red,
          onChanged: viewModel.onSwitchPressed,
        ),
      ),
    )
  ),

https://flutteragency.com/how-to-solve-no-material-widget-found-in-flutter/

 

 

728x90
반응형