Flutter

[Flutter] Custom Widget 만들기

hminor 2023. 7. 29. 14:31

Custom Widget 만들기

  • 레이아웃 용 위젯들이 너무 길다면
    • 커스텀 위젯으로 대체할 수 있다.
      • stless를 입력 후 tab 또는 enter를 입력하면 자동으로 완성된다.
      class  extends StatelessWidget {
        const ({super.key});
      
        @override
        Widget build(BuildContext context) {
          return const Placeholder();
        }
      }
      
      • 이후 Class명을 파스칼 케이스로 작명 후 return 으로 넘길 레이아웃을 작성하면 된다.
      • 그래서 아래와 같이 작성하게 되면 같은 작업을 반복할 필요도 없고 코드의 가독성 또한 좋아지게 된다.
      • 다만 단점으로는 state 관리에 대한 어려움이 있다.
      • 그래서 재사용이 많은 UI들을 커스텀 위젯으로 만들면 좋다.
      import 'package:flutter/material.dart';
      
      void main() {
        runApp(const MyApp());
      }
      
      class MyApp extends StatelessWidget {
        const MyApp({super.key});
      
        @override
        Widget build(BuildContext context) {
      
          return MaterialApp(
            home: Scaffold(
              appBar: AppBar(
      
              ),
              body: ShopItem()
            ),
          );
        }
      }
      
      class ShopItem extends StatelessWidget {
        const ShopItem({super.key});
      
        @override
        Widget build(BuildContext context) {
          return const SizedBox(
            child: Text('하잉'),
          );
        }
      }
      
    • 그리고 굳이 클래스를 만들지 않아도 변수에 담아서 사용을 할 수도 있다.
      • 다만 성능 이슈와 같은 문제들이 있기에
      • 변수엔 서비스 사용 중 변하지 않아도 괜찮은 것들만 담아서 사용하기!
      • 즉, 아래와 같은 코드 작성은 좋은 방법이 아니다.
      import 'package:flutter/material.dart';
      
      void main() {
        runApp(const MyApp());
      }
      
      const a =  SizedBox(
            child: Text('하잉'),
          );
      
      class MyApp extends StatelessWidget {
        const MyApp({super.key});
      
        @override
        Widget build(BuildContext context) {
      
          return MaterialApp(
            home: Scaffold(
              appBar: AppBar(
      
              ),
              body: a
            ),
          );
        }
      }
      
      
  • 그리고 세로로 여러개의 텍스트를 보여주고 싶다면
    • 그냥 Column() 안에 children으로 여러개 넣어주면 된다고 생각하지만
    • 앱에서는 위젯이 많다고 해서 스크롤바가 자동으로 생기지 않기에
    • ListView() 안에 채워주면 장점으로
    • 자동으로 스크롤바가 생기며, 스크롤 위치도 쉽게 확인이 가능하며, 메모리 절약도 할 수 있다.
      • 스크롤 위치 확인은 controller 속성으로 할 수 있다
      • 그리고 메모리 절약은 예를 들어 100개의 게시글 중 90번을 보고 있다면 보이지 않는 게시글은 메모리에서 지움으로써 절약을 할 수 있다.
  • 숙제
    • ListView와 Custom Widget을 활용해서 연락처 구현하기
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
    
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(
    
            ),
            body: ListView(
              children: [
                Row(
                  children: [
                    Icon(Icons.person, size: 50),
                    Text('홍길동', style: TextStyle(fontSize: 20, fontWeight: FontWeight.w400),)
                  ],
                ),
                Row(
                  children: [
                    Icon(Icons.person, size: 50),
                    Text('홍길동', style: TextStyle(fontSize: 20, fontWeight: FontWeight.w400),)
                  ],
                ),
                Row(
                  children: [
                    Icon(Icons.person, size: 50),
                    Text('홍길동', style: TextStyle(fontSize: 20, fontWeight: FontWeight.w400),)
                  ],
                ),
              ],
            ),
            bottomNavigationBar: BottomAppBar(),
          ),
        );
      }
    }
    
    class BottomAppBar extends StatelessWidget {
      const BottomAppBar({super.key});
    
      @override
      Widget build(BuildContext context) {
        return Container(
          height: 70,
          color: Colors.white,
          child: Expanded(
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                Icon(Icons.phone),
                Icon(Icons.textsms),
                Icon(Icons.person_pin_rounded),
              ],
            ),
          ),
        );
      }
    }