[FMX] TListView 더보기 버튼 구현하기

2017.09.20 13:49

모바일 앱을 개발할 때에 리스트 항목이 많은 경우, 한번에 가져오면 시간이 오래 걸려 좋지 않은 사용자 경험이 됩니다.


이 경우, 리스트 중 일부를 빠르게 표시하고, 리스트 끝으로 이동 시 추가로 표시하는 방식을 통해 문제를 해결할 수 있습니다.


이 글에서는, 

리스트뷰(TListView)의 목록 끝으로 이동 시, 더보기 버튼을 표시하도록 (매우 심플하게)구현합니다.

버튼 클릭 시 항목을 추가합니다.


이 글을 참고해 리스트 끝으로 이동 시 자동으로 항목을 추가하도록 구현할 수도 있습니다.


리스트뷰 더보기 버튼  구현하기

결과

결과 화면은 다음과 같습니다.


처음 24개 항목 표시 후, 목록 끝으로 이동 시 버튼이 표시되고, 버튼을 눌러 항목을 추가합니다.


구현방법

1) 더보기 버튼을 리스트뷰(TListView)에 올려놓고 감춥니다.(Visible := False)

2) 리스트뷰의 스크롤 이동(OnScrollViewChange) 이벤트 핸들러에서 제일 끝으로 이동한 경우 버튼을 표시합니다.


컴포넌트 구성은 아래와 같습니다.


구현된 주요 코드는 아래와 같습니다.

procedure TForm2.AddItem(ACount: Integer);
var
  I: Integer;
  Item: TListViewItem;
begin
  for I := 0 to ACOunt - 1 do
  begin
    Item := ListView1.Items.Add;
    Item.Text := 'Item ' + ListView1.Items.Count.ToString;
  end;
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
  AddItem(24);
  btnListViewMore.Visible := False;
end;

procedure TForm2.btnListViewMoreClick(Sender: TObject);
begin
  AddItem(6);
  btnListViewMore.Visible := False;
end;

procedure TForm2.ListView1Resized(Sender: TObject);
begin
  ListView1ScrollViewChange(Sender);
end;

procedure TForm2.ListView1ScrollViewChange(Sender: TObject);
var
  LastItemBottom, ListViewBottom: Single;
begin
  LastItemBottom := ListView1.GetItemRect(ListView1.ItemCount - 1).Bottom;
  ListViewBottom := ListView1.LocalRect.Bottom;

  btnListViewMore.Visible := ((LastItemBottom - ListViewBottom) < 30);
end;


샘플 프로젝트

ListViewMoreButton.zip


이 샘플에서는 더보기 버튼 클릭 시 단순하게 목록을 추가했습니다. 실무에서는 더보기 버튼 클릭시 추가 데이터를 수신 후 목록을 동적으로 갱신하도록 구현해야 합니다.


당겨서 새로고침(Pull to refresh) 구현하기

모바일 앱에서는 새로운 정보를 가져오기 위해 당겨서 새로고침 기능을 사용할 수 있습니다.

이 기능은 리스트뷰(TListView)의 속성을 이용해 구현할 수 있습니다.


PullToRefresh 속성을 True로 설정 시, 목록 상단에서 당겨서 새로고침 기능을 제공합니다.

위 동작이 발생하면 OnPullRefresh 이벤트가 발생합니다.


참고링크


저작자 표시 비영리 변경 금지
신고

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

[REST API] 다음 Kakao > 로컬 > 주소검색 연동하기

2017.09.18 15:06

다음 등의 포털 사에서는 자사 데이터 일부를 Open API로 공개하고 있습니다.

특히 지도나 주소, 검색 등은 직접 데이터를 수집하는 것보다 포털의 데이터를 활용하는 것이 개발 및 유지보수에 유리할 수 있습니다.


오늘은 데브기어 테크게시판을 통해 다음 카카오의 주소검색 API 연동을 문의주셔서 해당 내용을 공유합니다.


아래 샘플을 REST API를 이용해 카카오 주소 검색 Open API와 연동하는 내용입니다.

(카카오 Open API의 대부분은 REST API를 제공합니다. )


해당 내용을 잘 익혀서 다양한 Open API를 여러분의 앱에서 활용하실 수 있습니다.


카카오 개발자 > 로컬 : https://developers.kakao.com/docs/restapi/local


카카오 Open API를 연동하기 위해서는 앱을 등록하고, 앱 키를 받아야 합니다.(해당 내용의 설명은 생략합니다.)

카카오 개발자 > 내 애플리케이션 : https://developers.kakao.com/apps


위 링크를 참고해 개발했으며, 제일 문제가 됐던 부분은 HTTP 해더에 Authorization 값을 추가하는 부분입니다.


연동한 결과는 아래와 같습니다.


주요 코드는 아래와 같습니다.

uses
  REST.TYpes;

const
  API_KEY = '';
{
  https://developers.kakao.com/ 등록 > 앱 생성 > 앱키(REST API 키)를 위(API_KEY)에 입력
}

procedure TForm2.Button1Click(Sender: TObject);
begin
  RESTRequest1.Params.ParameterByName('query').Value := Edit1.Text;

  RESTRequest1.Execute;
end;

procedure TForm2.FormCreate(Sender: TObject);
var
  Param: TRESTRequestParameter;
begin
  RESTClient1.BaseURL := 'https://dapi.kakao.com';
  RESTClient1.Accept := 'application/json, text/plain; q=0.9, text/html;q=0.8,';
  RESTClient1.AcceptCharset := 'UTF-8, *;q=0.8';

  RESTRequest1.Resource := 'v2/local/search/address.json?query={query}';
  Param := RESTRequest1.Params.AddHeader('Authorization', 'KakaoAK ' + API_KEY);
  Param.Options := [TRESTRequestParameterOption.poDoNotEncode];

  RESTResponseDataSetAdapter1.RootElement := 'documents';
end;

샘플 프로젝트

KakaoLocalLocation.zip


문단제목



저작자 표시 비영리 변경 금지
신고

험프리.김현수 Delphi/C++Builder

[FMX] 폼의 높이를 애니메이션으로 변경하기, 툴바를 끌어 폼 이동하기

2017.09.12 15:59

약국용 라디오 어플을 개발하는 개발사에서는, 오래전부터 PC 기반으로만 라디오 서비스를 하고 있습니다.

해당 개발사에서는 노후된 앱을 최신 운영체제(윈도우 10 등) 지원과 모바일 확장을 위해 파이어몽키로 재개발 중입니다.

(파이어몽키는 윈도우, OSX, iOS, 안드로이드를 하나의 소스코드로 개발할 수 있습니다.)


개발 중 몇가지 질문을 주셔서 기술지원 후 해당 내용 일부를 공유합니다.


이 글에서는 다음 내용의 구현 방법을 소개합니다.

1, 폼의 일부영역 보이기/가리기(Collapse)

2, Border가 없는 폼에서 특정영역(Toolbar)을 마우스로 이동하기


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

1, 폼의 일부영역 보이기/가리기(Collapse)

이 기능은 TFloatAnimation 컴포넌트를 사용해 손쉽게 구현할 수 있었습니다.

(파이어몽키에는 애니메이션과 효과를 기본 컴포넌트로 제공합니다.)


TFloatAnimation은 지정 된 시작과 끝 Float 값에 대해 애니메이션 되면 값이 변경할 수 있어, 크기, 위치, 각도, 투명도 등을 천천히 변경할 수 있습니다.


하지만, 폼의 높이(Height) 속성에는 FloatAnimaion을 지정할 수 없어, 폼에 레이아웃 컴포넌트를 놓고, 레이아웃 컴포넌트의 높이를 변경시키고, 변경 시 발생하는 OnProcess 이벤트에서 폼의 높이를 조정하도록 구현했습니다.


위 기능의 코드는 아래와 같습니다.

procedure TForm2.FormCreate(Sender: TObject);
begin
  Self.BorderStyle := TFmxFormBorderStyle.None;

  FOrgHeight := lytMain.Height;
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
  lytMain.Align := TAlignLayout.None;
  FloatAnimation1.Duration := 0.5;
  if lytMain.Height = 0  then
  begin
    FloatAnimation1.StartValue := 0;
    FloatAnimation1.StopValue := FOrgHeight;
    FloatAnimation1.Start;
  end
  else
  begin
    FOrgHeight := lytMain.Height;
    FloatAnimation1.StartValue := FOrgHeight;
    FloatAnimation1.StopValue := 0;
    FloatAnimation1.Start;
  end;
end;

procedure TForm2.FloatAnimation1Finish(Sender: TObject);
begin
  lytMain.Align := TAlignLayout.Client;
end;

procedure TForm2.FloatAnimation1Process(Sender: TObject);
begin
  // 레이아웃 크기 조정 시 폼의 크기 조정
  Self.Height := Trunc(ToolBar1.Height + lytMain.Height) + 1;
end;


2, Border가 없는 폼에서 특정영역을 마우스로 이동하기

테두리가 없는 폼에서 제목등의 특정영역을 마우스로 끌어 이동하기 위해 다음 코드를 사용했습니다.

(해당 코드는 윈도우와 OSX(맥)에서 모두 동작합니다.)

procedure TForm2.ToolBar1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Single);
begin
  if (Button = TMouseButton.mbLeft) then StartWindowDrag;
end;




저작자 표시 비영리 변경 금지
신고

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

[FMX] iOS 시스템 볼륨 제어하기

2017.09.08 15:21

엠바카데로 블로그에 HARUYUKI MOHRI가 작성한 C++빌더로 iOS 시스템 볼륨 제어하는 내용이 있어 델파이로 작업해 봤습니다.


원글 : https://community.embarcadero.com/blogs/entry/how-to-control-the-system-audio-volume-of-ios?utm_source=Facebook_Organic&utm_medium=social


아래와 같이 Up/Down 버튼을 누르면 시스템 볼륨을 제어합니다.




MPVolumeView 클래스(iOSapi.MediaPlayer.pas)와 UISlider 클래스(iOSapi.UIKit.pas)를 사용했습니다.


uses 절에 "iOSapi.MediaPlayer, iOSapi.UIKit" 추가해야 합니다.


다음 2개 변수를 선언해야 합니다.

  private
    { Private declarations }
    FMPVolumeView: MPVolumeView;
    FSlider: UISlider;

구현된 델파이 코드는 아래와 같습니다.

procedure TForm1.FormCreate(Sender: TObject);
var
  I, J: Integer;
begin
  FMPVolumeView := TMPVolumeView.Create;

  I := 0;
  J := FMPVolumeView.subviews.count;

  if I = J then
  begin
    log.d('');
  end;

  if FMPVolumeView.subviews.count > 0 then
  begin
    FSlider := TUISlider.Wrap(FMPVolumeView.subviews.objectAtIndex(0));
    FSlider.setValue(0.0);
  end;
end;

procedure TForm1.btnVolumeUpClick(Sender: TObject);
var
  Vol: Single;
begin
  Vol := FSlider.value;
  FSlider.setValue(Vol + 0.1);
end;

procedure TForm1.btnVolumeDownClick(Sender: TObject);
var
  Vol: Single;
begin
  Vol := FSlider.value;
  FSlider.setValue(Vol - 0.1);
end;


샘플 프로젝트

iOSVolumeControl.zip


참고 링크

저작자 표시 비영리 변경 금지
신고

험프리.김현수 분류없음

TListView 행별로 배경색 설정 및 글꼴변경하기

2017.09.08 10:56

리스트뷰(TListView)는 많은 데이터를 목록으로 표시하기 위한 컴포넌트입니다.

스와이프(스크롤) 속도가 빠른 대신 항목 구성하기가 까다롭습니다.


이번 글에서는 리스트뷰 표현 방식 중 DynamicAppearance(동적 외관구성)를 이용해 외관 구성 후, 아래 기능을 구현했습니다.

1) 표시 항목을 추가(현재 2개, 여러 항목 표시가능)

2) 조건에 따라 배경색상을 변경

3) 조건에 따라 글꼴 변경


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

(아이폰에서는 "여자" 글꼴을 Bold로 주니 글자가 약간 커지네요.)



구현한 내용은 아래와 같습니다.

화면구성

대표 컴포넌트는 리스트뷰(TListView)와 이미지리스트(TImageList)입니다.

이미지 리스트에는 2개의 색상 이미지(16x16)를 추가했습니다.


리스트뷰의 ItemAppearance.ItemAppearance를 DynamicAppearance로 설정했습니다.


아이템 오브젝트는 문자를 표현할 Text 항목 2개와 배경을 표현할 Image 항목 총 3개로 구성했습니다.

(Image 항목을 추가한 이유는 Rectangle과 같은 도형을 지원했다면 도형의 배경으로 처리했겠지만, 지원하지 않아 이미지를 이용해 배경으로 처리했습니다.)


코드작성

코드의 주요 기능은 2가지 입니다.

1) 리스트뷰 아이템(TListViewItem)의 값에 따라 배경색 및 글꼴 설정

2) 리스트뷰 크기 변경(OnResized 이벤트) 시 항목너비 조정


참고로 리스트뷰 아이템 서식 변경의 경우 OnUpdateObjects 이벤트에서 처리했지만, 

코드로 목록을 추가하는 경우, 추가하는 시점에 서식을 설정할 수도 있습니다.

procedure TForm1.FormCreate(Sender: TObject);
begin
  ListView1.ItemSpaces := TBounds.Create(RectF(0, 0, 0, 0));
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Item: TListViewitem;
begin
  Item := ListView1.Items.Add;
  Item.Data['Text1'] := '김현수';
  Item.Data['Text2'] := '남자';
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  Item: TListViewitem;
begin
  Item := ListView1.Items.Add;
  Item.Data['Text1'] := '아이유';
  Item.Data['Text2'] := '여자';
//  (Item.Objects.ObjectByName('Image2') as TListItemImage).Bitmap := ImageList1.Bitmap(TSizeF.Create(16, 16), 1);
end;

function FindTextObject(const AListView: TListView; AName: string): TCommonObjectAppearance;
var
  Obj: TCommonObjectAppearance;
begin
  Result := nil;

  for Obj in AListView.ItemAppearanceObjects.ItemObjects.Objects do
  begin
    if Obj.Name = AName then
      Exit(Obj as TCustomTextObjectAppearance);
  end;
end;

procedure TForm1.ListView1Resized(Sender: TObject);
var
  Text1, Text2: TCommonObjectAppearance;
begin
  Text1 := FindTextObject(ListView1, 'Text1');
  Text2 := FindTextObject(ListView1, 'Text2');

  Text1.Width := ListView1.Width / 2;
  Text2.PlaceOffset.X := Text1.Width;
  Text2.Width := ListView1.Width / 2;
end;

procedure TForm1.ListView1UpdateObjects(const Sender: TObject;
  const AItem: TListViewItem);
var
  ImageItem: TListItemImage;
  TextItem: TListItemText;
begin
  ImageItem := AItem.Objects.DrawableByName('Image2') as TListItemImage;
  TextItem := AItem.Objects.DrawableByName('Text2') as TListItemText;

  if Assigned(ImageItem) then
  begin
    if AItem.Data['Text1'].ToString = '김현수' then
      ImageItem.Bitmap := ImageList1.Bitmap(TSizeF.Create(16, 16), 0)
    else
      ImageItem.Bitmap := ImageList1.Bitmap(TSizeF.Create(16, 16), 1)
    ;
    ImageItem.Visible := True;
  end;

  if Assigned(TextItem) then
  begin
    if Textitem.Text = '여자' then
      Textitem.Font.Style := [TFontStyle.fsBold, TFontStyle.fsItalic];
  end;
end;

샘플 프로젝트


위 구성은 리스트뷰 항목별로 배경과 글꼴을 설정했습니다.

위 내용을 참고하면, 각 항목의 위치, 크기 등을 자유자제로 편집할 수 있어 활용도는 무궁무진할 것으로 보입니다.


좋은 아이디어가 있다면, 저에게도 알려주셔서 공유 부탁드립니다.


참고자료


델파이 기본샘플을 적극 참고했습니다.


ListView 관련 샘픙은 기본 설치 경로 기준 아래와 같습니다.(10.2 도쿄 기준)
C:\Users\Public\Documents\Embarcadero\Studio\19.0\Samples\Object Pascal\Multi-Device Samples\User Interface\ListView


다음과 같은 샘플들이 있습니다.

그중 CustomAdapter와 ListViewImageIndex 샘플을 많이 참고했습니다.


CustomAdapter

웹상의 이미지를 표시하고, 상단에 큼지막한 이름과 하단에 설명과 버튼을 구성합니다.

목록의 크기를 이미지에 맞게 조정합니다.



ListViewImageIndex

리스트뷰와 데이터셋을 라이브바인딩과 코드를 이용해 목록을 구성합니다.

이미지는 이미지리스트를 활용합니다.


기타 다른 샘플들도 참고할 만한 내용이 많습니다. 다른 샘플들은 직접 둘러보시고 도움을 받으시기 바랍니다.

저작자 표시 비영리 변경 금지
신고

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