Delphi FMX TListView ScrollTo does not work correctly

210 Views Asked by At

I have set Item as DynamicAppearance. Items are diferent sizes because I recalcualte needed size OnUpdateObject event. Visualy everything looks as needed but it looks like ScrollTo does not see/know this and jumps somehere not there it should.

Tried to:

procedure ListViewScrollTo(const aListView: TListview);
var i, lHeight: Integer;
begin
    aListView.Repaint;
    lHeight := 0;
    for i := 0 to aListView.Items.Count - 1 do
    begin
    if i = aListView.ItemIndex then
      break;
    lHeight := lHeight + aListView.Items[i].Height  + Round(aListView.ItemSpaces.top + aListView.ItemSpaces.Bottom);
  end;
  aListView.strong textScrollViewPos := lHeight;
end;

But ListView.Items[i].Height is 0 moast of the time. Dont know why.

Here is my code that runs on OnUpdateObject (Bits and pices arround the web)

function GetTextHeight(const D: TListItemText; const Width: single; const Text: string): integer;
var
  Layout: TTextLayout;
begin
  Layout := TTextLayoutManager.DefaultTextLayout.Create;
  try
    Layout.BeginUpdate;
    try
      Layout.Font.Assign(D.Font);
      Layout.VerticalAlign := D.TextVertAlign;
      Layout.HorizontalAlign := D.TextAlign;
      Layout.WordWrap := D.WordWrap;
      Layout.Trimming := D.Trimming;
      Layout.MaxSize := TPointF.Create(Width, TTextLayout.MaxLayoutSize.Y);
      Layout.Text := Text;
    finally
      Layout.EndUpdate;
    end;
    //Size needs to be amanded for Scale oz Pixel density...
    Result := Round(Layout.Height * GetScreenScale);
  finally
    Layout.Free;
  end;

end;


function ListViewAutoSize(const Sender: TObject; const AItem: TListViewItem; aCustomItemTextName: string): Integer;
var
  Drawable: TListItemText;
  Text: string;
  AvailableWidth: Single;
  Names: TStringList;
  SumHeight: Single;
begin
  TListView(Sender).BeginUpdate;
  SumHeight := 0;
  Names := TStringList.Create;
  try
    Names.Delimiter := ';';
    Names.StrictDelimiter := True;
    Names.DelimitedText := aCustomItemTextName;
    //do this for all items in aCustomUtemTextName
    for var I := 0 to Names.Count - 1 do
    begin
      AvailableWidth := TListView(Sender).Width - TListView(Sender).ItemSpaces.Left - TListView(Sender).ItemSpaces.Right;

      Drawable := TListItemText(AItem.View.FindDrawable(Names[i])); //find item by name
      if assigned(Drawable) then
      begin
        //found
        if Drawable.Visible then
        begin
          Text := Trim(Drawable.Text);
          if Text <> '' then
          begin
            SumHeight := SumHeight;
            Drawable.PlaceOffset.Y := SumHeight ;
            Drawable.Height := GetTextHeight(Drawable, AvailableWidth, Text) * GetScreenScale;
            SumHeight := SumHeight + Drawable.Height;
            AItem.Height := Round(SumHeight);
            Drawable.Width := AvailableWidth;
          end else begin
            Drawable.Height := 0;
          end;
        end;
      end;
    end;
    //set Item size that everything is visible...
    AItem.Height := Round(SumHeight);
    Result := AItem.Height;
  finally
    Names.Free;
  end;
  TListView(Sender).EndUpdate;
end;
0

There are 0 best solutions below