programing

위젯을 만드는 함수와 클래스의 차이점은 무엇입니까?

nasanasas 2020. 11. 28. 09:36
반응형

위젯을 만드는 함수와 클래스의 차이점은 무엇입니까?


StatelessWidget 을 서브 클래 싱하는 대신 일반 함수를 사용하여 위젯을 만들 수 있다는 것을 깨달았습니다 . 예를 들면 다음과 같습니다.

Widget function({ String title, VoidCallback callback }) {
  return GestureDetector(
    onTap: callback,
    child: // some widget
  );
}

이것은 본격적인 클래스보다 훨씬 적은 코드가 필요하기 때문에 흥미 롭습니다 . 예:

class SomeWidget extends StatelessWidget {
  final VoidCallback callback;
  final String title;

  const SomeWidget({Key key, this.callback, this.title}) : super(key: key);

  @override
  Widget build(BuildContext context) {
      return GestureDetector(
        onTap: callback,
        child: // some widget
      );
  }
}

그래서 저는 궁금했습니다. 위젯을 만드는 함수와 클래스 사이에 구문 외에 다른 점이 있습니까? 함수를 사용하는 것이 좋은 습관입니까?


요약 : 재사용 가능한 위젯 트리를 만들기 위해 클래스보다 함수를 사용하지 마십시오 . 대신 항상 StatelessWidget 으로 추출하십시오 .


클래스 대신 함수를 사용 하는 것에는 차이가 있습니다. 즉, 프레임 워크는 함수를 인식하지 못하지만 클래스를 볼 수 있습니다.

다음 "위젯"기능을 고려하십시오.

Widget functionWidget({ Widget child}) {
  return Container(child: child);
}

이 방법으로 사용 :

functionWidget(
  child: functionWidget(),
);

그리고 그것은 동등한 클래스입니다.

class ClassWidget extends StatelessWidget {
  final Widget child;

  const ClassWidget({Key key, this.child}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: child,
    );
  }
}

다음과 같이 사용 :

new ClassWidget(
  child: new ClassWidget(),
);

서류상 둘 다 똑같은 일을하는 것 같습니다 : Create 2 Container, 하나는 다른 하나에 중첩됩니다. 그러나 현실은 약간 다릅니다.

함수의 경우 생성 된 위젯 트리는 다음과 같습니다.

Container
  Container

클래스를 사용하는 동안 위젯 트리는 다음과 같습니다.

ClassWidget
  Container
    ClassWidget
      Container

이는 위젯을 업데이트 할 때 프레임 워크가 작동하는 방식을 근본적으로 변경하기 때문에 매우 중요합니다. 다음은 선별 된 차이점 목록입니다.

  1. 클래스:

    • 성능 최적화 허용 (const 생성자, 연산자 == 재정의,보다 세분화 된 재 빌드)
    • 핫 리로드
    • 위젯 인스펙터 (debugFillProperties)에 통합됩니다.
    • 키를 정의 할 수 있습니다.
    • 컨텍스트 API를 사용할 수 있습니다.
    • 모든 위젯이 동일한 방식으로 사용되는지 확인 (항상 생성자)
    • 서로 다른 두 레이아웃 사이를 전환하면 리소스가 올바르게 처리되는지 확인합니다 (함수는 이전 상태를 재사용 할 수 있음).
  2. 기능 :

    • 코드가 적습니다 (그리고 거기에서도 클래스를 함수만큼 작게 만드는 코드 생성기를 만들었습니다 : functional_widget )
    • ?

결론은 이미 매우 명확해야합니다.

위젯을 만드는 데 함수를 사용하지 마십시오 .


이 문제에 대해 지난 2 일 동안 조사했습니다. 저는 다음과 같은 결론에 도달했습니다. 앱의 일부를 기능으로 나누는 것은 괜찮습니다. 이러한 함수가를 반환하는 것이 이상적 StatelessWidget이므로를 만드는 것과 같은 최적화를 수행 할 수 StatelessWidget const있으므로 필요하지 않은 경우 다시 빌드하지 않습니다. 예를 들어 다음 코드는 완벽하게 유효합니다.

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      ++_counter;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
            const MyWidgetClass(key: const Key('const')),
            MyWidgetClass(key: Key('non-const')),
            _buildSomeWidgets(_counter),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }

  Widget _buildSomeWidgets(int val) {
    print('${DateTime.now()} Rebuild _buildSomeWidgets');
    return const MyWidgetClass(key: Key('function'));

    // This is bad, because it would rebuild this every time
    // return Container(
    //   child: Text("hi"),
    // );
  }
}

class MyWidgetClass extends StatelessWidget {
  const MyWidgetClass({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    print('${DateTime.now()} Rebuild MyWidgetClass $key');

    return Container(
      child: Text("hi"),
    );
  }
}

함수를 사용하면 const StatelessWidget. 내가 틀렸다면 나를 고쳐주세요.


Flutter 위젯을 호출 할 때 const 키워드를 사용해야합니다. 예를 들면const MyListWidget();

참고 URL : https://stackoverflow.com/questions/53234825/what-is-the-difference-between-functions-and-classes-to-create-widgets

반응형