Flutter Custom Widget

강정우·2023년 5월 8일
0

Flutter&Dart

목록 보기
9/87
post-thumbnail

class

  • widget은 객체라는 것을 앞서 언급하였다. 또 거의 대부분의 value가 obj라는 것을 알 수 있었다.
    즉, 이 obj가 dart의 fundamental한 concept이라 하였다.

  • 그런데 이 class는 java를 했다면 obj와 매우 밀접한 연관관계를 갖고있다고 볼 수 있다.
    하지만 이를 이해하려면 dart는 결국 객체지향 언어라는 것을 알아야한다.

  • 이는 Primitive한 원시타입은 물론이고 요상한 Widgets, Config Obj도 모두 객체라는 것에서 알 수 있다.
    그런데 이 obj는 어디서 타입과 변수명등 즉, 데이터 구조를 지정해줄까? 바로 class이다.

  • 이는 런타임에 생성될 때 어떤 종류의 데이터가 개체에 저장될지 정의하고 메서드라는 추가 함수가 어떤 개체에 저장될지도 정의한다.

  • 그럼 각각의 class는 어디서 확인할까? 물론 간편하게 IDE에서 호버링으로도 확인할 수 있지만 공식문에서 자세히 확인 가능하다.

  • 따라서 우리는 이를 기바으로 코드에서 클래스와 생성자 함수를 다루게 된다.
    그런 다음 장치에서 응용 프로그램이 실행되고 코드가 위에서 아래로 실행되면 실제 개체는 생성(인스턴스화)되고 메모리에 저장되는 동작과정을 지닌다.

빌딩블록 만들기

  • 위에서 주구장창 설명했듯 dart는 결국 객체지향 언어이고 이를 빌딩블록을 하려면 react처럼 함수형 프로그래밍이 아닌 객체지향으로 작성해줘야한다.
    그리고 이때 우리는 규칙을 지켜야한다.
  1. 반드시 snake_case 혹은 PascalCase로 작성할 것.

    • 하지만 PascalCase를 강권한다.
  2. StatelessWidget 를 extends하기

    • 이는 플러터에서 요구되는 데이터와 기본적인 논리를 추가한다.
      그래야만 내가 작성한 class를 위젯으로 사용해 UI에 추가할 수 있다.
  3. build함수 작성하기

    • build함수에 return type(Widget)을 지정하고 @overide 를 해준다.
    • build함수는 context라는 인수를 받고 이는 메타데이터 객체이다. 이는 전체 위젯 트리에 있는 이 위젯에 관한 유용한 정보를 포함하고 있는 객체를 뜻한다.
    • 그러면 플러터가 사용자 인터페이스를 렌더링할 때 이 메서드를 호출하고
      그러면 플러터는 build함수가 반환하는 위젯을 받고 사용자 인터페이스에 반영되도록 한다.
      이 build함수에서 return을 사용하면 플러터가 위젯에 액세스하거나 위젯의 조합에 액세스할 수 있다
  4. const 키워드로 생성자 선언하기

    • 고유한 생성자 함수로 계속하여 반복적으로 obj를 찍어낼 때 마다 새로 생성자 함수를 메모리에 할당하면 안 되니 const로 1번만 할당하는 것이다.

빌딩블록 만들기+

  • 여기서 생성자함수를 따로 만들진 않았지만 모든 클래스에 자동으로 추가되기 때문에 우리가 명시적으로 추가하지 않아도 되며
    또 사용도한 가능하다.

  • 물론 사용은 가능하나 추가적인 설정이나 구성을 추가하고 싶다면 이 위젯이 생성되는 시점에서 생성자함수를 명시하여 추가해줘야한다.

생성자 함수 만들기

  • 그냥 자기 이름을 반복하면 된다. 이때 생성자함수는 return값을 명시하지 않아도 괜찮다.
  • 또한 여기서 초기화 작업을 할 수 있다.

  • 그리고 StatelessWidget을 상속받는한 key인수를 받아서 StatelessWidget에 보내야한다. 이때 2가지 방법이 있다.
  1. 생성자 함수 이름과 괄호 뒤에 콜론을 추가하고 그 후에 변수 초기화 작업을 할 수 있다.

  • super을 키워드를 통해 상속받은 부모 클래스에 접근:하여 부모클래스의 생성자함수를 호출super()하여 key 값을 설정해주는데 이를 상속받은 클래스의 key값을 넣어준다.
  1. 위 코드가 복잡하여 dart는 shor-cut을 제공한다.
  • Super.Key를 쓰면 Key라는 이름의 인수를 받고 자동으로 슈퍼클래스(부모)로 전달된다.
    그래서 간편하게 StatelessWidget에 key를 보낼 수 있다.

파일 자르기

  • 이제 위 절차에 따라 class를 선언었다면 이제 이를 빌딩블록화를 해줘야한다.

naming

  • lib 폴더 밑에 파일을 생성하여 넣어주면 된다.

  • 이때 반드시 snake_case로 작성해야하며 모두 소문자로 작성해야한다.

  • 이때 파일 하나당 주요 함수나 주요 클래스를 기준으로 나눠주면 좋다.

빌딩블록 사용하기

  • package: 라는 키워드를 사용하고 뒤엔 현재 프로젝트 이름을 갖다 적으면 된다. 그리고 path대로 타고 들어가서 작성해주면 된다.

Variables (var)

  • Variables는 데이터 container이다.
    Variables는 데이터 컨테이너이고 이 기능은 모든 프로그래밍 언어에서 존재한다.
    왜냐하면 모든 프로그래밍 언어는 값과 관련된 일을 많이 하기 때문이다.

  • 자 예를 들어보자.

  • 아래와 같이 Alignment 객체에 들어가 해당 객체를 수정하고 싶다면 이를 변수로서 선언하면 된다는 뜻인데

  • 이때 2가지 문제가 발생한다. 1. null은 할당이 안 된다. 2. 올바르지 않은 const 키워드 사용이다.
    하지만 원인은 2번이라고 볼 수 있다.

  • 2번이 왜 뜨냐면

class GradientContainer extends StatelessWidget {
  const GradientContainer({super.key});
  
  Widget build(ctx) {
    return Container(
      decoration: const BoxDecoration(
        gradient: LinearGradient(
          colors: [
            Color.fromARGB(255, 121, 56, 231),
            Color.fromARGB(255, 224, 108, 245),
          ],
          begin: startAlignment,
          end: endAlignment,
        ),
      ),
      child: const Center(
        child: StyledText(),
      ),
    );
  }
}
  • BoxDecoration 밑으로 값이 변하지 않다고 상수처리를 해놨으나 startAlignment, endAlignment는 var로 변환 가능성이 있다고 선언해버렸기 때문이다.
    그래서 const 키워드를 재배치 해줘야한다.

var의 타입

  • var도 타입을 지정할 수 있다.

  • 위 사진을 보면 따로 지정하지 않아도 dart가 인지하는데 이는 dart가 최초로 할당된 값을 토대로 타입을 추론하고 있다.
    이때 var 변수를 선언할 때 따로 타입을 지정하지 ㅇ낳는다는 이는 dynamic 타입이 되는데 이는 dart만의 특별한 타입이다.

  • 물론 이처럼 사용하는 것을 지양해야한다. 마치 TS에서 any를 남발하는 것과 같으며 이는 type을 지정해주는 장점과 이유를 무시해버리는 행동이기 때문이다.

  • 그래도 정 사용하고 싶다면 앞에 type을 먼저 지정 후 optional keyword ? 를 통해 null이거나 값이 들어있거나 라는 선택지를 부여해주면 된다.

final

var startAlignment = Alignment.topLeft;
  • 물론 혼자하면 상관없지만 많은 개발자들이 함께 작업을 하는 거라면 아무래도 제약조건을 걸어주는 것이 에러를 최소화 할 수 있는 방향일 것이다.

const vs final

  • 둘다 변경할 수 없는 상수를 선언하는 것인데 그럼 이 둘의 차이점은 무엇일까?

  • const는 컴파일 타임 상수 즉, 코드를 discord할 때 할당된다는 것이다.
    즉, app이 실행될 때 실행된다는 것이다.

  • 반면 final은 컴파일되는 시점이 아닌 코드가 실행된 후에 할당된다. 뭔가 time stamp 처럼 해당 코드가 실시될 때! 딱 결정되고 그 이후로는 바뀔 수 없다고 생각하면 된다.

  • 즉, 선언 시점은 const가 더 선행된다.

profile
智(지)! 德(덕)! 體(체)!

0개의 댓글