Question

I am creating Firemonkey Mobile Application on Delphi XE5. I would like to use TPaintBox component to display some text (2000+ words with special characters, tables). I have created form with TListBox and special TListBoxItem type TListBoxItemPaintBox = Class(TListBoxItem) containing TPaintBox inside. Idea is very simple - on TPaintBox I will draw data, while TListBox will take care about scrolling.

When this app is compiled under Win32, everything runs perfect, scrolling is quick. But when I compile this app on my phone with Android, app becomes useless - scrolling is incredibly ss-ll-oooo-www.

Here is complete code to my app (simplified, but working version)

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Layouts,
  FMX.ListBox, FMX.StdCtrls, FMX.Objects, System.UIConsts;

type
  TListBoxItemPaintBox = Class(TListBoxItem)
    public
      pbMain: TPaintBox;
      List: TStringList;
      constructor Create(AOwner: TComponent); override;
      procedure pbMainOnPaint(Sender: TObject; Canvas: TCanvas);
  end;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Button1: TButton;
    lbMain: TListBox;
    procedure Button1Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
{TListBoxItemPaintBox}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
constructor TListBoxItemPaintBox.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  self.Height := 200;
  self.Text := '';

  pbMain := TPaintBox.Create( self );
  pbMain.Parent := self;
  pbMain.Align := TAlignLayout.alClient;
  pbMain.OnPaint := pbMainOnPaint;
end;

procedure TListBoxItemPaintBox.pbMainOnPaint(Sender: TObject; Canvas: TCanvas);
// pbMain.OnPaint := pbMainOnPaint;
var
  i, vertPos: Integer;
  s: String;
  rect: TRectF;
begin
  vertPos := 0;

  Canvas.BeginScene;
  Canvas.Clear(claWhite);

  Canvas.Fill.Color := claBlack;
  Canvas.Font.Style := [];
  Canvas.Font.Size := 12;

  for i := 0 to List.Count-1 do
    begin
      s := List[i];
      rect.Create(0,
                  vertPos,
                  Canvas.TextWidth(s),
                  vertPos+Canvas.TextHeight(s));
      Canvas.FillText(rect, s, false, 255, [], 
                    TTextAlign.taLeading ,TTextAlign.taCenter);
      vertPos := vertPos + 15;
    end;

  self.Height := vertPos;
  pbMain.Canvas.EndScene;
end;

//%%%%%%%%%%%%%%%%%%%%%
{TForm1}
//%%%%%%%%%%%%%%%%%%%%%
procedure TForm1.Button1Click(Sender: TObject);
var
  ListTemp: TStringList;
  aListBoxItem: TListBoxItemPaintBox;
  i: Integer;
begin
  ListTemp := TStringList.Create;
  for i := 0 to 80 do
    ListTemp.Add(IntToStr(i));

  aListBoxItem := TListBoxItemPaintBox.Create( lbMain );
  aListBoxItem.List := ListTemp;
  lbMain.AddObject(aListBoxItem);
end;

end.

Does anyone has idea how to make this working on Android? Is there some more appropraite way of using TPaintBox or should I use completely different component?

Was it helpful?

Solution

ListBox is not the correct container for having so many records on as it is very slow but it's indeed a lot more customizable than others. You will have to use the ListView component in order to achieve speed and normal scrolling. It's going to be somewhat painful to make it display all the things you want to because it's kinda restricted from its own. You will have to make your own Style on which the items will listen to when they are created by code.

Here is a really really useful video on how to achieve this from Ray Konopka.

http://www.youtube.com/watch?v=XRj3qjUjBlc&list=PLwUPJvR9mZHiaYvH9Xr7WuFCVYugC4d0w&index=23

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top