WaitDialog 구현 - 재사용 가능한 프레임 구현하기

2017.12.06 13:36

얼마전 진행한 모바일 개발 컨설팅에서 블루투스 장비와 연결 후 기다리는 동안 표시할 화면이 필요했습니다.

WaitDialog라는 화면을 만들었는데 이 화면은 앞으로도 많이 사용하게 될 것 같아 TFrame을 이용해 재사용 가능하도록 구현해 봤습니다.


WaitDialg 구현에 아래 기술을 사용했습니다.

1) TFrame

2) 클래스 메소드

3) 싱글톤 패턴


이 내용을 학습하면

1) 자주 사용하는 화면을 프레임으로 제작 해 재사용 할 수 있습니다.

2) 클래스 메소드를 활용해 코드를 짧게 사용 할 수 있습니다.

결과화면

결과 화면은 아래와 같습니다.


구현한 내용

화면구성

파이어몽키 프레임을 이용해 WaitDialog 화면을 구성했습니다.

파이어몽키에서 TFrame은 폼디자이너에서 화면을 구성할 수 있는 객체입니다. UI 컴포넌트와 논비주얼 컴포넌트를 화면에 추가하고 사용할 수 있습니다.


WaitDialog 코드

type
  TWaitDialog = class(TFrame)
    rctBackground: TRectangle;
    lytMessage: TLayout;
    rctMessageBG: TRectangle;
    lblMessage: TLabel;
    AniIndicator1: TAniIndicator;
    Timer: TTimer;
    procedure TimerTimer(Sender: TObject);
  private
    class var FInstance: TWaitDialog;
  private
    { Private declarations }
  public
    { Public declarations }
    destructor Destroy; override;

    class procedure Show(ATitle: string = ''; ATimeout: Integer = -1);
    class procedure Hide;
  end;

implementation

{$R *.fmx}

{ TFrame1 }

class procedure TWaitDialog.Show(ATitle: string; ATimeout: Integer);
begin
  if not Assigned(FInstance) then
    FInstance := Create(nil);

  FInstance.Parent := Application.MainForm;
  FInstance.Align := TAlignLayout.Client;
  FInstance.BringToFront;
  FInstance.Visible := True;

  if ATitle <> '' then
  begin
    FInstance.lblMessage.Text := ATitle;
  end;

  if ATimeout > 0 then
  begin
    if ATimeout < 1000 then
      ATimeout := 1000;
    FInstance.Timer.Interval := ATimeout;
    FInstance.Timer.Enabled := True;
  end;
end;

class procedure TWaitDialog.Hide;
begin
  if not Assigned(FInstance) then
    Exit;
  FInstance.Visible := False;
  FInstance.DisposeOf;
end;

procedure TWaitDialog.TimerTimer(Sender: TObject);
begin
  Timer.Enabled := False;
  Hide;
end;

destructor TWaitDialog.Destroy;
begin
  FInstance := nil;

  inherited;
end;

initialization
finalization
  TWaitDialog.Hide;

클래스 메소드

WaitDialog를 보여주고 감추는 메소드(Show, Hide)를 클래스 메소드(class procedure, class function)로 구현했습니다.

클래스 메소드는 클래스를 생성하기 전에 호출할 수 있는 메소드로 Create 등이 대표적인 클래스 메소드입니다.


클래스 메소드를 사용한 이유는 WaitDialog를 호출하는 측의 코드를 최대한 짧게 작성할 수 있도록 하기위해서 입니다.


싱글톤 패턴

클래스 메소드를 사용 후 객체를 생성하기 위해 클래스 변수(class var)를 사용했습니다. 


객체 생성은 Show 메소드에서, 객체 해제는 Hide 메소드에서 합니다. Hide 시키지 않고 앱을 종료하는 경우를 대비 finalization에서 Hide 메소드를 호출 합니다.


싱글톤 패턴은 프로그램 내에서 객체를 하나만 생성하는 디자인 패턴입니다. 위 예제에서 객체는 하나만 생성합니다.

만약, 다른 곳에서 싱글톤 객체가 필요하다면 아래와 같은 코드를 추가할 수 있습니다.

class function TWaitDialog.Instance: TWaitDialog; begin if not Assigned(FInstance) then FInstance := Create; Result := FInstance; end; class procedure TWaitDialog.ReleaseInstance; begin if Assigned(FInstance) then FInstance.DisposeOf; end; initialization finalization TWaitDialog.ReleaseInstance;

위와 같이 구현하면 TWaitDialog.Instance를 이용해 접근하면 객체를 유일하게 사용할 수 있습니다.(너무 멀리까지 나갔네요.^^)

사용방법

uses FMX.WaitDialog;

  TWaitDialog.Show;
  TWaitDialog.Show('잠시만 기다려 주세요.');
  TWaitDialog.Show('잠시만 기다려 주세요.', 10000);

  TWaitDialog.Hide;

uses 절에 유닛을 추가하고, Show 클래스 메소드를 다양한 방식으로 호출해 화면을 표시합니다.

비동기 동작이 완료된 경우 Hide 클래스 메소드를 호출하면 화면이 감춰집니다.


데모 프로젝트

WaitDialog.zip


험프리.김현수 파이어몽키