Перейти к содержанию
Fire Monkey от А до Я
  • 0

Отображение картинок в ListView


ra.eremeev

Вопрос

Добрый день!

Друзья, помогите, пожалуйста, побороть одну проблему: при загрузке картинок в ListView картинки не отображаются до выполнения какого-либо действия с самим ListView (например, скрола или простого прикосновения к нему). Т.е., требуется прикоснуться к компоненту, чтобы картинки появились.

Проблема возникает только с собственноручно созданным объектом TListViewImage. При использовании для вывода изображений "стандартный" Image (например, ItemAppearance=ImageListItem), проблем не возникает :(

Но иногда требуется больше одного изображения и необходимо создавать свои.

С использованием решения по загрузке изображений из инета от ZuBy сделал минималистичный проект (нет ничего лишнего), отражающий суть проблемы.

Буду ОЧЕНЬ признателен за помощь!

LoadBitmaps.zip

Ссылка на комментарий

Рекомендуемые сообщения

  • 0
В 06.02.2019 в 14:48, Евгений Корепов сказал:

procedure TForm1.ClearListViewAndCancelAsynchronousRequests();

Var I : Integer;

begin

for I := 0 to FAsyncResultList.Count - 1 do

  if FAsyncResultList.Items <> Nil then

    if Not FAsyncResultList.Items.IsCompleted then

      FAsyncResultList.Items.Cancel;

FListViewUpdating:=True;

for I := ListView1.Items.Count - 1 downto 0 do

  ListView1.Items.Delete(I);

FListViewUpdating:=False;

end;

 

Евгений, спасибо громадное за код!!! Красиво и лаконично!

Но под Rio всё равно крэшится с ошибкой, если приложение закрывать раньше, чем успевают загрузиться фотки:
Project Test21.exe raised exception class ENetHTTPClientException with message 'Error receiving data: (12017) Операция отменена'.
 

Поправил вот так:

procedure TForm1.ClearListViewAndCancelAsynchronousRequests();
var
  I: Integer;
begin
  FListViewUpdating := True; // Запрещаем продолжать загружать фотки (если ещё не успели загрузиться все)
  while FAsyncResultList.Count > 0 do  // Дожидаемся окончания выполнения всех IAsyncResult.Cancel, несмотря на асинхронность
  begin
    for I := FAsyncResultList.Count - 1 downto 0 do
      if Assigned(FAsyncResultList.Items) and (not FAsyncResultList.Items.IsCompleted) then
        FAsyncResultList.Items.Cancel
      else
        FAsyncResultList.Delete(I); // Заодно удаляем элементы (раннее не удалялись - утечка памяти)
  end;
  ListView1.Items.Clear;
  FListViewUpdating := False;
end;

 

=====

Тоже, кстати, пару раз поймал ошибку в  TMonitor и в TDictionary. 

Выяснил, что возникает из-за обращения к элементам списка в LoadImage, когда их уже нет. Пофиксил так (отмечено синим):

 

procedure TForm1.LoadImage(const AItem: TListViewItem; const AListItemImage : TListItemImage);

var
  K: Integer; // Анонимная процедура захватывает локальную переменную, а не обращается к AItem, которой уже может не быть в момент _окончания_ скачивания фотки
  AAsyncResult: IAsyncResult;
begin
  if Not Assigned(AItem) or Not Assigned(AListItemImage) then
    Exit;
  if AItem.Data['ImageState'].AsInteger <> ListViewItemImageEmpty then
    Exit;
  if AItem.Data['ImageURL'].AsString.IsEmpty then
    Exit;
  AItem.Data['ImageState'] := ListViewItemImageLoading;
  K := AItem.Index; // Запоминаем индекс в локальную K, которая уйдёт в анонимку (время жизни K > времени жизни анонимки)
  FAsyncResultList.Items[K] := FHTTPClient.BeginGet(
    procedure (const ASyncResult: IAsyncResult)
    var
      AHTTPResponse: IHTTPResponse;
    begin
      if ASyncResult.IsCancelled then
        Exit;
      try
        AHTTPResponse := THTTPClient.EndAsyncHTTP(ASyncResult);
        if Not Assigned(AHTTPResponse) then
          Exit;
        if AHTTPResponse.StatusCode <> 200 then
          Exit;
      except
        Exit;
      end;

      TThread.Synchronize(Nil,
        procedure
        begin
          if FListViewUpdating then // Выходим, так как внутри анонимной процедуры AItem или AListItemImage - не сброшены в nil, хотя их уже может и не быть
            Exit;  // Кстати, наверное, правильнее было бы вместо проверки FListViewUpdating  использовать и/или условие: if ASyncResult.IsCancelled then Exit; ?

          if Not Assigned(AItem) or Not Assigned(AListItemImage) then
            Exit;
          AListItemImage.BeginUpdate;
          AListItemImage.Bitmap := TBitmap.Create;
          AListItemImage.Bitmap.LoadFromStream(AHTTPResponse.ContentStream);
          AListItemImage.EndUpdate;
          AItem.Data['ImageState'] := ListViewItemImageLoaded;
          FAsyncResultList.Items[K] := nil; // Наверное, это присвоение лучше вытащить наверх, перед проверкой всех условий? Ведь фотка скачалась успешно...  Или не надо?
        end
      );
    end,
    AItem.Data['ImageURL'].AsString
  );
end;

====

Прогонял много раз, клацал по кнопке один и много раз и закрывал сразу приложение, ошибки пока больше не появлялись... Тьфу-тьфу-тьфу.... :)

 

Ссылка на комментарий
  • 0
12 часов назад, Евгений (KeeperWorld) сказал:

 

Прогонял много раз, клацал по кнопке один и много раз и закрывал сразу приложение, ошибки пока больше не появлялись... Тьфу-тьфу-тьфу.... :)

 

Приложите, пожалуйста весь код целиком, я думаю многим пригодится. 

Ссылка на комментарий
  • 0
3 часа назад, #WAMACO сказал:

Приложите, пожалуйста весь код целиком, я думаю многим пригодится. 

Да там всё Евгений Корепов сделал уже. Я только три копейки своих добавил... :)

Вот конечный код:

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, System.Net.HttpClient, System.Generics.Collections,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.ListView.Types, FMX.ListView.Appearances, FMX.ListView.Adapters.Base,
  FMX.Controls.Presentation, FMX.StdCtrls, FMX.Layouts, FMX.ListView;

const
  ListViewItemImageEmpty = -1;
  ListViewItemImageLoading = 0;
  ListViewItemImageLoaded = 1;

type
  TForm1 = class(TForm)
    ListView1: TListView;
    Layout1: TLayout;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure ListView1UpdatingObjects(const Sender: TObject; const AItem: TListViewItem; var AHandled: Boolean);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    FListViewUpdating : Boolean;
    FHTTPClient : THTTPClient;
    FAsyncResultList : TList<IAsyncResult>;
    procedure LoadImage(const AItem: TListViewItem; const AListItemImage : TListItemImage);
    procedure ClearListViewAndCancelAsynchronousRequests();
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.FormCreate(Sender: TObject);
begin
  listview1.ItemIndex := 0;
  listview1.ItemAppearance.ItemAppearance := 'Custom';
  listview1.ItemAppearanceObjects.ItemObjects.Accessory.Visible := False;

  FHTTPClient := THTTPClient.Create;
  FAsyncResultList := TList<IAsyncResult>.Create;
  FListViewUpdating := False;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  ClearListViewAndCancelAsynchronousRequests();
  FListViewUpdating := True;
  FreeAndNil(FAsyncResultList);
  if Assigned(FHTTPClient) then
    FHTTPClient.Free;
end;

procedure TForm1.ClearListViewAndCancelAsynchronousRequests();
var
  I: Integer;
begin
  FListViewUpdating := True; // Запрещаем продолжать загружать фотки (если ещё не успели загрузиться все)
  while FAsyncResultList.Count > 0 do  // Дожидаемся окончания выполнения всех IAsyncResult.Cancel, несмотря на асинхронность
  begin
    for I := FAsyncResultList.Count - 1 downto 0 do
      if Assigned(FAsyncResultList.Items) and (not FAsyncResultList.Items.IsCompleted) then
        FAsyncResultList.Items.Cancel
      else
        FAsyncResultList.Delete(I); // Заодно удаляем отработанные элементы
  end;
  ListView1.Items.Clear;
  FListViewUpdating := False;
end;

procedure TForm1.Button1Click(Sender: TObject);
var 
  I: Integer;
  Item: TListViewItem;
  ARandom: Integer;
begin
  ClearListViewAndCancelAsynchronousRequests();
  //Формирование нового списка
  for I := 1 to 10000 do
  begin
    FAsyncResultList.Add(nil);
    FListViewUpdating := True;
    Item := listview1.Items.Add;
    Item.Height := 45;
    Randomize;
    ARandom := Random(6);
    case ARandom of
      0 : Item.data['ImageURL'] := 'http://fire-monkey.ru/uploads/monthly_2017_06/me.thumb.jpg.966ddc17d5602ee14feb43479c1f6963.jpg';
      1 : Item.data['ImageURL'] := 'http://fire-monkey.ru/uploads/monthly_2018_05/B-IpGQmVgTM.thumb.jpg.2ebeb0bd766ab7cf19f10195d6ea2be9.jpg';
      2 : Item.data['ImageURL'] := 'http://fire-monkey.ru/uploads/monthly_2016_04/10.png.b9ab371e8fd38172fee96bcf75fb6699.thumb.png.b0685259b03bfff540903913845532a5.png';
      3 : Item.data['ImageURL'] := 'https://secure.gravatar.com/avatar/9942c50b1641a921c52d4b389bd718d6?d=http://fire-monkey.ru/uploads/monthly_2017_12/K_member_87.png';
      4 : Item.data['ImageURL'] := 'http://fire-monkey.ru/uploads/monthly_2016_11/photo-1529.png.7267be10b59f950b7c5bb3f34a60901e.thumb.png.22027ae85266216220310ed694d57628.png';
      5 : Item.data['ImageURL'] := 'http://fire-monkey.ru/uploads/profile/photo-thumb-115.jpg';
    end;
    Item.Data['ImageState'] := ListViewItemImageEmpty;
    FListViewUpdating := False;
    Item.Adapter.ResetView(Item);
  end;
end;

procedure TForm1.LoadImage(const AItem: TListViewItem; const AListItemImage : TListItemImage);
var
  K: Integer; // Анонимная процедура захватывает локальную переменную, а не обращается к AItem, которой уже может не быть в момент _окончания_ скачивания фотки
  AAsyncResult: IAsyncResult;
begin
  if Not Assigned(AItem) or Not Assigned(AListItemImage) then
    Exit;
  if AItem.Data['ImageState'].AsInteger <> ListViewItemImageEmpty then
    Exit;
  if AItem.Data['ImageURL'].AsString.IsEmpty then
    Exit;
  AItem.Data['ImageState'] := ListViewItemImageLoading;
  K := AItem.Index; // Запоминаем индекс в локальную K, которая уйдёт в анонимку (время жизни K > времени жизни анонимки)
  FAsyncResultList.Items[K] := FHTTPClient.BeginGet(
    procedure (const ASyncResult: IAsyncResult)
    var
      AHTTPResponse: IHTTPResponse;
    begin
      if ASyncResult.IsCancelled then
        Exit;
      try
        AHTTPResponse := THTTPClient.EndAsyncHTTP(ASyncResult);
        if Not Assigned(AHTTPResponse) then
          Exit;
        if AHTTPResponse.StatusCode <> 200 then
          Exit;
      except
        Exit;
      end;

      TThread.Synchronize(Nil,
        procedure
        begin
          if FListViewUpdating or ASyncResult.IsCancelled then // Выходим, так как внутри анонимной процедуры AItem или AListItemImage - не сброшены в nil, хотя их уже может и не быть
            Exit;
          if Not Assigned(AItem) or Not Assigned(AListItemImage) then
            Exit;
          AListItemImage.BeginUpdate;
          AListItemImage.Bitmap := TBitmap.Create;
          AListItemImage.Bitmap.LoadFromStream(AHTTPResponse.ContentStream);
          AListItemImage.EndUpdate;
          AItem.Data['ImageState'] := ListViewItemImageLoaded;
          FAsyncResultList.Items[K] := nil; 
        end
      );
    end,
    AItem.Data['ImageURL'].AsString
  );
end;

procedure TForm1.ListView1UpdatingObjects(const Sender: TObject; const AItem: TListViewItem; var AHandled: Boolean);

  function SetupImageObject(const AName: String; AWidth, AHeight, X , Y: Single; AAlign, AVertAlign: TListItemAlign): TListItemImage;
  var
    LIT: TListItemText;
  begin
    Result := TListItemImage(AItem.View.FindDrawable(AName));
    if Result = Nil then
    begin
      // Создаём картинку
      Result := TListItemImage.Create(AItem);
      Result.Name := AName;
      Result.Bitmap := nil;
      Result.OwnsBitmap := True;
      // Создаём надпись
      LIT := TListItemText.Create(AItem);
      LIT.Name := 'LIT-' + AItem.Index.ToString;
      LIT.Width := 100;
      LIT.Height := 22;
      LIT.PlaceOffset.X := X + AWidth + 10;
      LIT.PlaceOffset.Y := Y;
      LIT.Text := LIT.Name;
      LIT.Visible := True;
    end;
    Result.Width := AWidth;
    Result.Height := AHeight;
    Result.PlaceOffset.X := X;
    Result.PlaceOffset.Y := Y;
    Result.Align := AAlign;
    Result.VertAlign := AVertAlign;
    Result.ScalingMode := TImageScalingMode.StretchWithAspect;
    Result.Visible := True;
  end;

Var 
  AListItemImage: TListItemImage;
begin
  if FListViewUpdating then
    Exit;
  AListItemImage := SetupImageObject('s_image', 35, 35, 0 , 0, TListitemalign.Leading, TListItemAlign.Center);
  LoadImage(AItem, AListItemImage);
  AHandled := True;
end;

end.

 

Изменено пользователем Евгений (KeeperWorld)
Ссылка на комментарий
  • 0
В 08.03.2019 в 20:42, Евгений (KeeperWorld) сказал:

Да там всё Евгений Корепов сделал уже. Я только три копейки своих добавил... :)

Вот конечный код:


unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, System.Net.HttpClient, System.Generics.Collections,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.ListView.Types, FMX.ListView.Appearances, FMX.ListView.Adapters.Base,
  FMX.Controls.Presentation, FMX.StdCtrls, FMX.Layouts, FMX.ListView;

const
  ListViewItemImageEmpty = -1;
  ListViewItemImageLoading = 0;
  ListViewItemImageLoaded = 1;

type
  TForm1 = class(TForm)
    ListView1: TListView;
    Layout1: TLayout;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure ListView1UpdatingObjects(const Sender: TObject; const AItem: TListViewItem; var AHandled: Boolean);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    FListViewUpdating : Boolean;
    FHTTPClient : THTTPClient;
    FAsyncResultList : TList<IAsyncResult>;
    procedure LoadImage(const AItem: TListViewItem; const AListItemImage : TListItemImage);
    procedure ClearListViewAndCancelAsynchronousRequests();
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.FormCreate(Sender: TObject);
begin
  listview1.ItemIndex := 0;
  listview1.ItemAppearance.ItemAppearance := 'Custom';
  listview1.ItemAppearanceObjects.ItemObjects.Accessory.Visible := False;

  FHTTPClient := THTTPClient.Create;
  FAsyncResultList := TList<IAsyncResult>.Create;
  FListViewUpdating := False;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  ClearListViewAndCancelAsynchronousRequests();
  FListViewUpdating := True;
  FreeAndNil(FAsyncResultList);
  if Assigned(FHTTPClient) then
    FHTTPClient.Free;
end;

procedure TForm1.ClearListViewAndCancelAsynchronousRequests();
var
  I: Integer;
begin
  FListViewUpdating := True; // Запрещаем продолжать загружать фотки (если ещё не успели загрузиться все)
  while FAsyncResultList.Count > 0 do  // Дожидаемся окончания выполнения всех IAsyncResult.Cancel, несмотря на асинхронность
  begin
    for I := FAsyncResultList.Count - 1 downto 0 do
      if Assigned(FAsyncResultList.Items) and (not FAsyncResultList.Items.IsCompleted) then
        FAsyncResultList.Items.Cancel
      else
        FAsyncResultList.Delete(I); // Заодно удаляем отработанные элементы
  end;
  ListView1.Items.Clear;
  FListViewUpdating := False;
end;

procedure TForm1.Button1Click(Sender: TObject);
var 
  I: Integer;
  Item: TListViewItem;
  ARandom: Integer;
begin
  ClearListViewAndCancelAsynchronousRequests();
  //Формирование нового списка
  for I := 1 to 10000 do
  begin
    FAsyncResultList.Add(nil);
    FListViewUpdating := True;
    Item := listview1.Items.Add;
    Item.Height := 45;
    Randomize;
    ARandom := Random(6);
    case ARandom of
      0 : Item.data['ImageURL'] := 'http://fire-monkey.ru/uploads/monthly_2017_06/me.thumb.jpg.966ddc17d5602ee14feb43479c1f6963.jpg';
      1 : Item.data['ImageURL'] := 'http://fire-monkey.ru/uploads/monthly_2018_05/B-IpGQmVgTM.thumb.jpg.2ebeb0bd766ab7cf19f10195d6ea2be9.jpg';
      2 : Item.data['ImageURL'] := 'http://fire-monkey.ru/uploads/monthly_2016_04/10.png.b9ab371e8fd38172fee96bcf75fb6699.thumb.png.b0685259b03bfff540903913845532a5.png';
      3 : Item.data['ImageURL'] := 'https://secure.gravatar.com/avatar/9942c50b1641a921c52d4b389bd718d6?d=http://fire-monkey.ru/uploads/monthly_2017_12/K_member_87.png';
      4 : Item.data['ImageURL'] := 'http://fire-monkey.ru/uploads/monthly_2016_11/photo-1529.png.7267be10b59f950b7c5bb3f34a60901e.thumb.png.22027ae85266216220310ed694d57628.png';
      5 : Item.data['ImageURL'] := 'http://fire-monkey.ru/uploads/profile/photo-thumb-115.jpg';
    end;
    Item.Data['ImageState'] := ListViewItemImageEmpty;
    FListViewUpdating := False;
    Item.Adapter.ResetView(Item);
  end;
end;

procedure TForm1.LoadImage(const AItem: TListViewItem; const AListItemImage : TListItemImage);
var
  K: Integer; // Анонимная процедура захватывает локальную переменную, а не обращается к AItem, которой уже может не быть в момент _окончания_ скачивания фотки
  AAsyncResult: IAsyncResult;
begin
  if Not Assigned(AItem) or Not Assigned(AListItemImage) then
    Exit;
  if AItem.Data['ImageState'].AsInteger <> ListViewItemImageEmpty then
    Exit;
  if AItem.Data['ImageURL'].AsString.IsEmpty then
    Exit;
  AItem.Data['ImageState'] := ListViewItemImageLoading;
  K := AItem.Index; // Запоминаем индекс в локальную K, которая уйдёт в анонимку (время жизни K > времени жизни анонимки)
  FAsyncResultList.Items[K] := FHTTPClient.BeginGet(
    procedure (const ASyncResult: IAsyncResult)
    var
      AHTTPResponse: IHTTPResponse;
    begin
      if ASyncResult.IsCancelled then
        Exit;
      try
        AHTTPResponse := THTTPClient.EndAsyncHTTP(ASyncResult);
        if Not Assigned(AHTTPResponse) then
          Exit;
        if AHTTPResponse.StatusCode <> 200 then
          Exit;
      except
        Exit;
      end;

      TThread.Synchronize(Nil,
        procedure
        begin
          if FListViewUpdating or ASyncResult.IsCancelled then // Выходим, так как внутри анонимной процедуры AItem или AListItemImage - не сброшены в nil, хотя их уже может и не быть
            Exit;
          if Not Assigned(AItem) or Not Assigned(AListItemImage) then
            Exit;
          AListItemImage.BeginUpdate;
          AListItemImage.Bitmap := TBitmap.Create;
          AListItemImage.Bitmap.LoadFromStream(AHTTPResponse.ContentStream);
          AListItemImage.EndUpdate;
          AItem.Data['ImageState'] := ListViewItemImageLoaded;
          FAsyncResultList.Items[K] := nil; 
        end
      );
    end,
    AItem.Data['ImageURL'].AsString
  );
end;

procedure TForm1.ListView1UpdatingObjects(const Sender: TObject; const AItem: TListViewItem; var AHandled: Boolean);

  function SetupImageObject(const AName: String; AWidth, AHeight, X , Y: Single; AAlign, AVertAlign: TListItemAlign): TListItemImage;
  var
    LIT: TListItemText;
  begin
    Result := TListItemImage(AItem.View.FindDrawable(AName));
    if Result = Nil then
    begin
      // Создаём картинку
      Result := TListItemImage.Create(AItem);
      Result.Name := AName;
      Result.Bitmap := nil;
      Result.OwnsBitmap := True;
      // Создаём надпись
      LIT := TListItemText.Create(AItem);
      LIT.Name := 'LIT-' + AItem.Index.ToString;
      LIT.Width := 100;
      LIT.Height := 22;
      LIT.PlaceOffset.X := X + AWidth + 10;
      LIT.PlaceOffset.Y := Y;
      LIT.Text := LIT.Name;
      LIT.Visible := True;
    end;
    Result.Width := AWidth;
    Result.Height := AHeight;
    Result.PlaceOffset.X := X;
    Result.PlaceOffset.Y := Y;
    Result.Align := AAlign;
    Result.VertAlign := AVertAlign;
    Result.ScalingMode := TImageScalingMode.StretchWithAspect;
    Result.Visible := True;
  end;

Var 
  AListItemImage: TListItemImage;
begin
  if FListViewUpdating then
    Exit;
  AListItemImage := SetupImageObject('s_image', 35, 35, 0 , 0, TListitemalign.Leading, TListItemAlign.Center);
  LoadImage(AItem, AListItemImage);
  AHandled := True;
end;

end.

 

FAsyncResultList.Items[K] := FHTTPClient.BeginGet(...

странно, на этой строчке получаю ошибку "arguments out of range"

Ссылка на комментарий
  • 0

В ранее приложенном проекте код как у Евгений (KeeperWorld)

В итоге я сделал так:

procedure TForm1.Button2Click(Sender: TObject);
var
 xJS, xObj: ISuperObject;
 vItemList, iHeader: TListViewItem;
 aJSON, URL: string;
 j: integer;
begin
...
 with xJS.A['data'] do 
  begin
   for j := 0 to length - 1 do
    begin
     xObj := O[j];
    vItemList:= aLV.Items.Add;
    with vItemList do
     begin
      Text := ...;
      Data['sign_URL'] := 'http://is.kidscoders.ru/'+xObj.S['students_photo'];
      Data['sign_Loaded'] := 0;
     end;
    end;
  end;
end;

procedure TForm1.LoadBitmapFromURL(const AURL: string; aBitmap: TBitmap);
var
  thread: TThread;
begin
  thread := TThread.CreateAnonymousThread(
    procedure
    var
      HTTP: THTTPClient;
      HttpResponse: IHttpResponse;
      Result: TMemoryStream;
      ResourceStream: TResourceStream;
    begin
      Result := TMemoryStream.Create;
      HTTP := THTTPClient.Create;
      try
        try
          HttpResponse:= HTTP.Get(AURL, Result);
          if (HTTPResponse.StatusCode <> 200) then //если нет изображения на сервере, то default img
           begin
            ResourceStream := TResourceStream.Create(hInstance, 'PngImage_1', RT_RCDATA);
            ResourceStream.Position := 0;
            Result.LoadFromStream(ResourceStream);
            FreeAndNil(ResourceStream);
           end;
          TThread.Synchronize(TThread.CurrentThread,
            procedure
            var
              aSourceBmp: TBitmap;
            begin
              aSourceBmp := TBitmap.Create;
              aSourceBmp.LoadFromStream(Result);
              if not aSourceBmp.IsEmpty then
              begin
                aBitmap.SetSize(aSourceBmp.Width, aSourceBmp.Height);
                aBitmap.CopyFromBitmap(aSourceBmp);
              end;
              FreeAndNil(aSourceBmp);
            end);
        except
           FreeAndNil(Result);
        end;
      finally
        FreeAndNil(Result);
        FreeAndNil(HTTP);
      end;
    end);
  thread.FreeOnTerminate := true;
  thread.start;

end;

procedure TForm1.aLVUpdatingObjects(const Sender: TObject;
  const AItem: TListViewItem; var AHandled: Boolean);
begin
if AItem.Data['sign_Loaded'].AsInteger = 0 then
 begin
  AItem.Data['sign_Loaded'] := 1;
  LoadBitmapFromURL(AItem.Data['sign_URL'].AsString, AItem.Bitmap);
 end;
end;

 

Изменено пользователем Dmitry Stolyarov
Ссылка на комментарий
  • 0
22 часа назад, Dmitry Stolyarov сказал:

собрал в отдельный проект с указанным кодом и в итоге совсем картинки не грузятся... 

Грузятся если заменить  if (FListViewUpdating) or (AAsyncResult.IsCancelled) then на  if (FListViewUpdating) or (AsyncResult.IsCancelled) then.

AAsyncResult у меня NIL

Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...