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

#WAMACO

Пользователи
  • Постов

    776
  • Зарегистрирован

  • Посещение

  • Победитель дней

    27

Активность репутации

  1. Like
    #WAMACO отреагировална OnePeople в Монополия   
    Делал чисто для себя! И только для своего удовольствия!
    Возможны ошибки!*(вернее точно есть))) 
    Графика не окончательная!
    Скриншоты сервер:
    Скриншоты клиент:
    Сервер на комп, клиент Android (должны находиться в одной сети)
    P/S И так как все устройства у меня Full HD, проверял только на них(
    Monopoly.rar
  2. Haha
    #WAMACO отреагировална gonzales в Переезд на 10.3 Rio   
    Чего Вы привязались к прогрессбару, это никак не связано с потоками, я просто уточнял, нужно ли обращаться к форме, созданной в потоке через синхронизацию. 
    Прочитайте посты выше, вроде как уже больше недели это обсуждаем.
     
    У вас очень странное представление о UI. Вы правда считаете, что я демонстрирую пользователю одновременно Сплэш, две формы, и повергающий его в экстаз прогрессбар??
  3. Like
    #WAMACO отреагировална haword в SpkToolbar   
    Перевел vcl/lcl версию тулбара для работы под fmx. Версия с очень грязным кодом, с кучей закоменченного кода, где что то тестировал что то работало, что то нет. Короче как есть так и выложил. Главное на данный момент - работает под Windows, macOS, Lubuntu 18.10. Но ошибок наверное куча так как полностью не проверял. Буду со временем править.
    https://github.com/haword/spktoolbar
  4. Thanks
    #WAMACO получил реакцию от Bob32 в Типовая задача доступа к данным - Нужен дельный совет   
    Пользуюсь и платной и бесплатной версией.
    Описание очень подробное http://www.tmssoftware.biz/Download/Manuals/tmsfmxcloudpackdevguide.pdf
    Все основные варианты взаимодействия описаны подробно.
  5. Like
    #WAMACO отреагировална krapotkin в Типовая задача доступа к данным - Нужен дельный совет   
    по вопросам.
    1) выбор на хостингах невелик - MySQL, Postgres.  Я PG выбрал чисто в силу интереса и он вроде поближе к стандартам, и у него ХП и другие всякие штуки.... Сижу на SWEB.RU. Опять же просто потому что давно. Есть и masterhost и любой другой крупный провайдер подойдет.
    2) не путаем хостинг с бэкенд-сервером (BAS). Типа Firebase или Amazon или еще туча. на хостинге у вас все свое. что написали то и работает. на BAS есть много приятных плюшек. Довольно платных ессно. Зато и push и email рассылки и админка...
    3) MSSQL не вариант. Веб в основном на Linux.
    4) обычно просто THttpClient. На нем нормально пишется клиентская часть API
    5) обычная схема. просто с нуля некоторые вещи пилить. зато бесплатно. Практика показывает что иногда лучше заплатить и получить богатое приложение сразу. но иногда как написал Евгений, потом можно упереться в ограничения сервисов. Но можно решать проблемы по мере поступления...
     
  6. Thanks
    #WAMACO получил реакцию от Bob32 в Типовая задача доступа к данным - Нужен дельный совет   
    http://mraven.ru/RavenLink.html
    вот еще простейший REST сервер. очень просто использовать. 
    причем не нужен architect edition, community подойдет даже
     
  7. Like
    #WAMACO отреагировална Евгений Корепов в Типовая задача доступа к данным - Нужен дельный совет   
    1. Хостинг рекомендую https://masterhost.ru/service/hosting/individual/ , это один из старейших и надежнейших хостеров России, там вы получите сразу все вам необходимое - MySQL, PHP любимой версии, если проект попрет, то сможете добавлять процессоры, память и т.д. Так же сможете зарегить домен под это дело, и при надобности получить SSL сертификат на этот домен. Все остальные хостинги  игнорируйте, по крайней мере Российские. За почти 20 лет использования, мастерхост ни разу не подвел, а только радовал новыми плюшками.

    Реализация в вашем случае примерно такая:
    1. MySQL на хостере - обеспечит вам работу и 10 миллионов активных пользователей. Но важно правильно  спланировать структуру базы, структуру таблиц и структуру индексов таблиц. Если вы в этом не профи, то лучше нанять профи - ибо это фундамент, который потом очень сложно будет изменить.
    2. PHP на хостере - прокладка между базой и запросами/ответами приложения. Рекомендую использовать самую свежую версию PHP, чтоб потом не пришлось перекраивать код удаляя deprecated функции и конструкции.
    3. Протокол обмена - REST. Не вздумайте погружаться в теорию, читать про RESTful и пытаться реализовывать, этим занимаются только люди под тяжелыми наркотиками и обычно без единого законченного реального проекта. Достаточно того что приложение будет отправлять на сервер GET запросы получать JSON ответы. Можете подогнать протокол под существующие в Delphi компоненты TRESTClient, а можете и сами на стороне приложения разгребать JSON и получать нужные данные. Это совсем не сложно.
    4. Приложение - посылает на сервер HTTP GET (ну или POST) запросы посредством THTTPClient, получает ответы в виде JSON, парсит их и так далее. Все содержимое предыдущего предложения - в отдельном потоке. Ну или используйте готовый TRESTClient - если готовы разбираться в нюансах его работы.
    Вот как то так.
  8. Like
    #WAMACO получил реакцию от Barbanel в Типовая задача доступа к данным - Нужен дельный совет   
    http://mraven.ru/RavenLink.html
    вот еще простейший REST сервер. очень просто использовать. 
    причем не нужен architect edition, community подойдет даже
     
  9. Like
    #WAMACO получил реакцию от Barbanel в Типовая задача доступа к данным - Нужен дельный совет   
    http://www.myclouddata.net
    и к ним компоненты для комфортной работы
    https://www.tmssoftware.com/site/tmsfmxcloudpack.asp
  10. Like
    #WAMACO получил реакцию от Ingalime в api KeyStore как реализовать в с++ Builder   
    Я думаю, что многие скажут спасибо, если Вы выложите сюда пример! Очень полезно! :))
  11. Like
    #WAMACO получил реакцию от Martifan в Загрузить изображение из библиотеки   
    https://github.com/rzaripov1990/ModernListView
  12. Like
    #WAMACO отреагировална Евгений (KeeperWorld) в Отображение картинок в ListView   
    Да там всё Евгений Корепов сделал уже. Я только три копейки своих добавил...
    Вот конечный код:
    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.  
  13. Like
    #WAMACO отреагировална Владимир Б. в TMemo для вывода лога тормозит   
    Подготовил за пол часа реализацию с цветом и стилем строки.
    Правда поменял форматирование кода под то которое мне удобней и понятней.

    FastMemo.zip
     
  14. Like
    #WAMACO отреагировална Евгений (KeeperWorld) в Отображение картинок в ListView   
    Евгений, спасибо громадное за код!!! Красиво и лаконично!
    Но под 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;
    ====
    Прогонял много раз, клацал по кнопке один и много раз и закрывал сразу приложение, ошибки пока больше не появлялись... Тьфу-тьфу-тьфу....
     
  15. Like
    #WAMACO отреагировална Bob32 в Ориентация на Север и углы наклона телефона   
    Ребята, есть проблемы.
    1) наши углы - не верные. особенно третий угол- он вообще непонятно что представляет.
    понимаю, что все что мы делаем - это вызываем стандартные методы (и они вызываются и работают) - но факт остается фактом.
    2) проблема, которую описал я  после первой компиляции программы- это не проблема ориентации экрана телефона! это другая проблема. моя проблема это то - что при одной и той же портретной ориентации телефона азимут на север изменится на 180% при подьеме телефона на 90 градусов (из горизонтальной плоскости в вертикальную - с той же ориентацией телефона).
     
    Для того, чтобы это было понятней - привожу две программы - первая это апк файл из первой статьи этого автора с хабра (где используется устаревший метод) - файл androidsensors.zip
    вторая программа - это наш проект в "доповоротоном" виде (в первоначальном виде) - файл sensman.zip
    третья программа - это наша программа с фиксом по ориантации экрана - sensman_fix.zip
    AndroidSensors.zip
    SensMan.zip
    SensMan_fix.zip
  16. Like
    #WAMACO получил реакцию от Barbanel в Скроллинг на канве   
    В RAD есть GetIt, там есть примеры игрушек. В частности, в одной из них плавно движется фон и еще объекты летают шустро достаточно.
    посмотрите...
    есть еще открытый движок (сделан на Delphi)
    https://github.com/castle-engine
    тоже интересный. 
  17. Like
    #WAMACO получил реакцию от Barbanel в Скроллинг на канве   
    Приходите в чат в Telegram., там был человек, который пишет игрушки на Delphi (по крайней мере был)
    Там если что, старожилы подскажут!
  18. Like
    #WAMACO получил реакцию от Сергей Сергеев в Редизайн, создание стиля, существующего приложения   
    Показали бы что ли... интересно ведь...
  19. Thanks
    #WAMACO отреагировална yooSee в Runtime permissions in Delphi 10.3 Rio   
    Всем привет, вот и я решил внести свою лепту в жизнь форума и сегодня мы разберемся с разрешениями на Delphi Rio под Андроид. 
    Для примера мы будем использовать разрешения на чтение и запись с памяти устройства, для начала в нашем проекте выставим в Delphi>Project>Application>Uses Permissions галочки на Read External Storage и Write External Storage.
    в uses проекта добавьте следующее
    uses System.Permissions, Androidapi.Jni.Os, Androidapi.Helpers, далее  создадим переменные
    var Form: TForm; .... FPermissionWrite: string; FPermissionRead: string; в Form.Create добавим следующий код
    procedure TForm.FormCreate(Sender: TObject); begin FPermissionWrite := JStringToString(TJManifest_permission.JavaClass.WRITE_EXTERNAL_STORAGE); //Значение на запись FPermissionRead := JStringToString(TJManifest_permission.JavaClass.READ_EXTERNAL_STORAGE); //Значение на чтение end; и теперь сам не посредственно запрос на подтверждение наших прав
    procedure TForm.Button1Click(Sender: TObject); begin PermissionsService.RequestPermissions ([FPermissionWrite, FPermissionRead], nil); end; //это вызовет окно с запросом разрешения прав ну и для проверки бросим на форму TMemo и пару TButton , в них реализуем сохранение и чтение из файла с памяти устройства
    procedure TForm.Button1Click(Sender: TObject); begin Memo1.Lines.LoadFromFile(TPath.Combine(TPath.GetSharedDocumentsPath, 'test.txt')); end; procedure TForm.Button2Click(Sender: TObject); begin Memo1.Lines.SaveToFile(TPath.Combine(TPath.GetSharedDocumentsPath, 'test.txt')); end; P.S. Напоминаю что для работы TPath нам понадобится подключить в Uses 
    uses System.system.ioutils; Надеюсь материал будет полезен! 
     
     
     

    video_2019-02-08_00-11-36.mp4 Permissions.zip
  20. Haha
    #WAMACO отреагировална Slym в Отображение картинок в ListView   
    Логика асинхронности принимает на вход анонимную процедуру для обработки результата, анонимная процедура захватывает переменные в зоне своего определения, а там хоть итем, хоть индекс, хоть блэкджек с простихоспаде чем попало...
  21. Like
    #WAMACO отреагировална Евгений Корепов в Отображение картинок в ListView   
    Проблемы не существует в принципе. Пытался разобраться в коде, но из за его полной не читабельности, плюнул, все удалил а написал заново. Решил для забавы использовать анонимный поток для загрузки картинки. По кнопке все грузится и сразу отображается. Никаких костылей не используется (ну кроме как AListItemImage.OwnsBitmap:=True, но и без этого все работает).
    Прилагаю код и архив проекта:
    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.ListView.Types, FMX.ListView.Appearances, FMX.ListView.Adapters.Base, System.Net.HttpClient, FMX.Controls.Presentation, FMX.StdCtrls, FMX.Layouts, FMX.ListView; const ListViewItemImageEmpy = -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); private { Private declarations } FListViewUpdating : Boolean; procedure LoadImage(const AItemIndex : Integer; AURL : String); public { Public declarations } end; var Form1: TForm1; implementation {$R *.fmx} procedure TForm1.FormCreate(Sender: TObject); begin FListViewUpdating:=False; end; procedure TForm1.Button1Click(Sender: TObject); var i:integer; item:TListViewItem; begin listview1.ItemIndex:=0; listview1.ItemAppearance.ItemAppearance:='Custom'; listview1.ItemAppearanceObjects.ItemObjects.Accessory.Visible:=false; //Очистка ListView for i := Listview1.ItemCount-1 downto 0 do ListView1.Items.Delete(i); //Формирование нового списка for i := 1 to 10 do begin Item:=listview1.Items.Add; item.Height:=45; FListViewUpdating:=true; item.data['ImageURL']:='http://fire-monkey.ru/uploads/monthly_2016_03/5-icon-29796ebcb510717e74ed258822feb2cc.png.365100cc218fe330c717aa80384fa4aa.png'; Item.Data['ImageState']:=ListViewItemImageEmpy; FListViewUpdating:=false; item.Adapter.ResetView(item); end; end; procedure TForm1.LoadImage(const AItemIndex : Integer; AURL : String); Var AHTTPClient : THTTPClient; AHTTPResponse : IHTTPResponse; begin AHTTPClient:=THTTPClient.Create(); AHTTPResponse:=AHTTPClient.Get(AURL); AHTTPClient.Free; if AHTTPResponse.StatusCode <> 200 then exit; TThread.Synchronize(Nil, procedure Var AListItemImage : TListItemImage; begin AListItemImage:=TListItemImage(ListView1.Items.Item[AItemIndex].View.FindDrawable('s_image')); if Assigned(AListItemImage) then begin AListItemImage.Bitmap:=TBitmap.Create; AListItemImage.Bitmap.LoadFromStream(AHTTPResponse.ContentStream); end; end ); 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 AImageState : Integer; AImageURL : String; AListItemImage : TListItemImage; begin AListItemImage:=TListItemImage(AItem.View.FindDrawable(AName)); if AListItemImage = Nil then begin AListItemImage:=TListItemImage.Create(AItem); AListItemImage.Name:=AName; AListItemImage.Bitmap:=Nil; AListItemImage.OwnsBitmap:=True; end; if AListItemImage.Bitmap=Nil then begin AImageState:=AItem.Data['ImageState'].AsInteger; if AImageState=ListViewItemImageEmpy then begin AImageURL:=AItem.Data['ImageURL'].AsString; if Not AImageURL.IsEmpty then begin AItem.Data['ImageState']:=ListViewItemImageLoading; TThread.CreateAnonymousThread( procedure begin LoadImage(AItem.Index, AImageURL); end).Start; end; end; end; AListItemImage.Width:=AWidth; AListItemImage.Height:=AHeight; AListItemImage.PlaceOffset.X:=X; AListItemImage.PlaceOffset.Y:=Y; AListItemImage.Align:=AAlign; AListItemImage.VertAlign:=AVertAlign; AListItemImage.ScalingMode:=TImageScalingMode.StretchWithAspect; AListItemImage.Visible:=True; Result:=AListItemImage; end; begin if FListViewUpdating then exit; SetupImageObject('s_image', 35, 35, 0 , 0, TListitemalign.Leading, TListItemAlign.Center); AHandled:=true; end; end.  
    LoadBitmaps.zip
  22. Like
    #WAMACO получил реакцию от Евгений Корепов в Всплывающее сообщение при его закрытии разворачивает приложение   
    Используйте механизм уведомлений, которые всплывают внизу, в трее.
  23. Like
    #WAMACO получил реакцию от Tumaso в Перевод VCL приложения на FMX. Подводные камни, стоит ли?   
    Хммм... не очень понятно, что у Вас там в продакшене...  у нас все работает тип-топ и все рады! и не один проект!
    может это не ваше?
  24. Thanks
    #WAMACO отреагировална Владимир Б. в Custom Font   
    В комплект к данному решению для Windows отлично подходит: https://github.com/TheOriginalBytePlayer/FireMonkey-Fonts , для загрузки шрифта из ресурсов.
    Так как решения для iOS и Android этого хорошо, только вот у Windows не меньше проблем с загрузкой шрифтов (их нужно принудительно ставить в систему, что не очень то и хорошо).
    Я почему-то было решил (исходя из написанного - "достаточно установить шрифт") - что RAD сам упакует использованные шрифты, но специально проверил - это не так. Начал искать решение, а оказывается у FMX есть свои нюансы по этому поводу.
    Решил поделиться найденным, может кому будет полезно.
  25. Thanks
    #WAMACO отреагировална RoschinSpb в Как убить кнопку кликнув на нее саму   
    Не ссоритесь девочки пож.
    Возвращаясь к сути вопроса. Основная сложность тут в том, что в Delphi нельзя разрушать экземпляр класса внутри метода этого класса за исключением тех случаев, когда метод использует только для разрушения Free, DisposeOf. Почему так, а не иначе, какие есть исключения и почему "уменяфсёработает" объяснять долго, поэтому в первом приближении предлагаю принять это за аксиому.
    Обработчики событий OnClick и пр. вызываются из методов классов, так что разрушать контрол внутри события нельзя от слова совсем. Кроме очевидных случаев типа Self.DisposeOf существуют более запутанные варианты, когда к примеру закрывает и разрушается форма, что приводит к разрушению всех дочерних контролов.
    Образно говоря, самоубийства строго запрещены, но не запрещено нанимать киллера и в качестве жертвы указывать себя. Т.е. должен быть некий другой (глобальный) объект который будет разрушать объекты, которые хотели бы самоубицо. Реализацию такого объекта можете придумать сами, или использовать TPurgatory (чистилище, в католическом учении — промежуточное место между раем и адом). Но чтобы убедиться в правильности работы можно создать своего наследника TButton в котором перекрыть деструктор и поставить в нем точку останова. При запуске в режиме отладки посмотрите стек вызова деструктора (надо быть внимательным, он может быть длиннющим), ни где в этом стеке не должно быть метода разрушаемого экземпляра. Если в Вы нашли метод разрушаемого объекта (за исключением вышеуказанных), то Ваш способ удаления работает не правильно и с некоторой долей вероятности будет приводить к AV и другим "неприятностям" которые почти невозможно отловить в режиме отладки.
×
×
  • Создать...