플러터에서 date picker를 기본 제공해 주고 있다.

정확히 말하면 flutter/material.dart에 showDatePicker함수가 

datepicker를 구현한다.

 

아래는 플러터사이트의 튜터리얼에 있는 사용법이다.

Future<DateTime> selectedDate = showDatePicker(
  context: context,
  initialDate: DateTime.now(),
  firstDate: DateTime(2018),
  lastDate: DateTime(2030),
  builder: (BuildContext context, Widget child) {
    return Theme(
      data: ThemeData.dark(),
      child: child,
    );
  },
);

 

이를 조금더 사용하기 쉽게 사용자 함수로 아래와 같이 만들었다.

return 값을 받는게 목적이다.

  Future selectDate() async {
    DateTime picked = await showDatePicker(
        context: context,
        locale: const Locale('ko', 'KO'),
        initialDate: DateTime.now(),
        firstDate: DateTime(2015),
        lastDate: DateTime(2030),
        builder: (BuildContext context, Widget child) {
          return Theme(
            data: ThemeData.dark(),
            child: child,
          );
        },
    );
    if(picked != null) {
      return picked.toString().substring(0, 10 );
    } else {
      return null;
    }
  }

 

버튼에 이벤트를 달아 실행하니

아래와 같은 에러가 발생했다.

 

 

 

에러 문구

The following NoSuchMethodError was thrown building Directionality(textDirection: ltr):
The method 'formatFullDate' was called on null.
Receiver: null
Tried calling: formatFullDate(Instance of 'DateTime')

 

formatFullDate라는 함수를 호출하면서 null 에러가 발생한것이다.

 

구글링 결과

국제 지역화 정보를 사용한다는 것을 셋팅하여야 한다는 것이다.

 

첫번째는 pubspec.yaml에서 페키지를 dependency 하고

main.dart에서 MateralApp에 localizationsDelegates 와 supportedLocales를 설정해 주면된다.

 

pubspec.yaml

  # lcalizations package
  flutter_localizations:
    sdk: flutter

 

main.dart

      child: MaterialApp(
          title: 'TEST APP',
          localizationsDelegates: [
            GlobalMaterialLocalizations.delegate,
            GlobalWidgetsLocalizations.delegate,
          ],
          supportedLocales: [
            const Locale('en', 'US'),
            const Locale('ko', 'KO'),
          ],

 

에뮬레이터 재시작을 하니 아주 예쁘게 달력이 출력된다.

 

 

테스트 결과 supportedLocales는 설정하지 않아도 달력이 정상적으로 출력된다.

한가지 아쉬운것은 달만 선택가능하는 기능을 제공하지 않는것이다.

 

플러터에서 문자열이 숫자형인지 체크하는 함수

플러터에서는 내장함수로 isNumeric, isNumber 와 같은 함수가 없어

사용자 정의 함수를 사용해야 함다.

 

인트형인지 체크

  bool isInt(String str) {
    if(str == null) {
      return false;
    }
    return int.tryParse(str) != null;
  }

str 이 null이면 인트형이 아님.

str을 tryParse해서 성고하면 숫자형 리턴, 실패하면 null 이 리턴되므로 null과 비교하여 성공여부 리턴한다.

즉, null 이면 인트형이 아니다.

 

더블형인지 체크

  bool isDouble(String str) {
    if(str == null) {
      return false;
    }
    return double.tryParse(str) != null;
  }

인트형 체크와 같다.

플러터에서 base64 문자열을 이미지로 표현하는 방식이다.

 

 

String base64 = 'data:image/png;base64,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';

 

기존에는 

 

Image.memory(base64Decode(base64))

 

dart가 업데이트 된 이후인지 몰라도 해당 아래와 같이 코드가 오류가 발생했다.

Invalid character (at character 5)
data:image/png;base64,

 

아래와 같이 소스를 수정하여 에러를 수정했지만, 

 

Image.memory(Uri.parse(base64).data.contentAsBytes())

 

일시적인 오류인지 원인은 아직 파악을 하지 못했다.

 

Flutter 작업을 하면서 이런 저런 문제를 해결 하는 재미도 쏠쏠하다.

 

플러트 프로젝트를 깃허브에서 가져와서 비주얼스튜디오 코드로 열면

처음에는 엑박이 뜨는 경우가 있습니다.

플러터 프로젝트에서 쓰는 라이브러리가 없기 때문인데요.

 

 

해결 방법은

cmd 창에서

flutter packages get

명령을 실행하면 아래와 같이 필요한 라이브러리를 가져옵니다.

 

 

또는 라이브러리가 선언된 파일인

pubspec.yaml 파일을 열고

마우스 오른쪽  버튼을 클릭하여

Get Packages 메뉴를 클릭하면 라이브러리를 가져오게 됩니다.

 

 

 

+ Recent posts