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

ENERGY

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

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

  • Посещение

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

    57

Сообщения, опубликованные ENERGY

  1. В VCL TPanel - это было окно (Window) со своим холстом (DC Canvas). И многие компоненты VCL это обертка над WinAPI - т.е. окна с определенным стилем который предлагает система.

    В FMX все отрисовывается собственным фреймворком (мультиплатформа ведь!), собственный рендер,  и теперь это не Window, соответственно у него нет дескриптора, как и у всех остальных визуальных компонентов FMX, кроме формы.  

    Расскажите лучше что вам нужно сделать.

  2. Вот эту еще почитайте статью, мне она больше понравилась.

    http://www.gunsmoker.ru/2013/05/modern-delphi.html

    Проблема DisposeOf в том, что он не освобождает память, а просто вызывает деструктор (к классу потом можно обратиться, и не будет Access Violation).

    На моб. платоформах я обычно иcпользую Free как и раньше, иногда FreeAndNil (если необходимо) т.к. на моб. платформах в отличии от десктопных платформ, вызов Free работает по другому . Если зайти в тело метода там будет комментарий: 

    // under ARC, this method isn't actually called since the compiler translates
    // the call to be a mere nil assignment to the instance variable, which then calls _InstClear

    В случае моб. платформ - Free обнуляет переменную, уменьшает ARC на единицу, затем проверяет счетчик ARC и если он = 0 - то вызывает деструктор. 

    Если объект где то присваивался, в какую либо еще переменную, и переменная не была обнулена, то его счетчик ссылок ARC > 0, то он не освободиться с вызовом Free, на эту тему есть баг (фича?) с reference procedure, который вроде уже исправили в Токио (я не проверял, т.к. пока токио нормально не работает под Android).

    А вот в случае с визуальными контролами, если нужно убрать контрол, надо использовать DisposeOf  иначе он останется на форме (может кто знает как его убрать при помощи Free, что и где обнулить? ).

  3. Вот вариант предложенный Равилем (я его немного изменил):

    Кстати на Android есть методы ОС для этого, они гораздо быстрее.

    uses System.Net.HttpClient

    function CheckInternet: boolean;
    begin
      Result := false;
      with THTTPClient.Create do
      try
        try
          Result := Head('http://google.com').StatusCode < 400;
        except
        end;
      finally
        Free;
      end;
    end;    

     

  4. А вам что нужно сделать? Я так понимаю вам нужно сделать список скинов?

    В коде я вижу что загружают style файлы. Понятно что нет смысла хардкодить их имена, можно положить их в спец. папку и затем просто  собирать список файлов *.style  и загружать нужный . А вот чтобы их туда поместить, - под Windows это делается просто, просто помещаете в отдельную папку, а под Android придется добавлять эти файлы в APK в Deploy, они потом при установке APK будут скопированы  автоматом. https://community.embarcadero.com/article/articles-tutorials/151-ui/927-deploying-and-accessing-local-files-on-ios-and-android

     

    Добавлять файлы в SQLite - не надо. Это лишнее процессорное время, ведь все равно придется формировать файл или TStream. А если вы имеете ввиду удаленную базу, то что мешает вам загружать эти файлы напрямую GET запросом, притом каждый лучше запаковать в ZIP - они же текстовые и раза в 3 будут меньше.

  5. Вы бы рассказали что там происходит в ролике, а то не у всех есть лишние 40 минут.

    Offtop 

    Есть один отличный прием, о котором мало кто знает.

    Если вам нужно поработать со стилем от моб. платформы на Windows (так гораздо быстрее программировать и отлаживать GUI) - можно просто открыть в текстовом редакторе style файл, найти в нем строку platform и заменить ее с напр. ANDROID на MSWINDOWS, сохранить, а затем загрузить в текущий Default стиль.

     

     

  6. Кстати на гитхабе есть ветка с примерами программ, которых нет в  Samples в последних версиях Delphi (часть примеров удалили в новых версиях), и там встречаются интересные примеры, втч. и связанные с 3D.

    Может это вам поможет. https://github.com/FMXExpress/Firemonkey/tree/master/Embarcadero

     

    Я бы на вашем месте скачал все примеры, распаковал их, а затем в Total Commander запустил бы поиск по тексту в *.pas файлах, например 'TViewport3D'

  7. Что то я не понял в чем проблема у автора. 

    Стандартный метод сортировки работает (Delphi Berlin).

     

    uses System.Generics.Defaults;
    ...
    procedure TForm1.ButtonSortClick(Sender: TObject);
    var
      Comparer: IComparer<TListViewItem>;
    begin
      Comparer := TDelegatedComparer<TListViewItem>.Create(
        function(const LeftItm, RightItm: TListViewItem): Integer
        begin
          Result := CompareText(LeftItm.Text, RightItm.Text);
        end);
    
      ListView1.Items.Sort(Comparer);
    end;

    А также можно по Data 

     

    procedure TForm1.ButtonSortClick(Sender: TObject);
    var
      Comparer: IComparer<TListViewItem>;
    begin
      Comparer := TDelegatedComparer<TListViewItem>.Create(
        function(const LeftItm, RightItm: TListViewItem): Integer
        begin
           Result := 0; //no change
           if LeftItm.Data['number'] > RightItm.Data['number'] then 
              Result := 1 //depend on sort order asc/desc
           else if LeftItm.Data['number'] < RightItm.Data['number'] then 
              Result := -1; //depend on sort order asc/desc
        end);
     
      ListView1.Items.Sort(Comparer);
    end;

     

    Не забудьте BeginUpdate - EndUpdate. 

    Напомню что к объектам ListViewItem можно обращаться не через Data['name'], а напрямую через индексы, что гораздо быстрее, т.к. не нужно сравнивать все строки в цикле, это важно при большом количестве Objects per Item (напр. больше 5 в режиме DynamicAppearance).

  8. Я не понял, нужно ли снимать эту галочку с libnative-activity.so чтобы поддерживались Intel устройства или нет?

    Что это за файл вообще, для чего он используется? И будет ли без него корректно работать программа.

    Для чего то ведь его включают в проект...

    Delphi Berlin.

  9. Создаете свой стиль для ListBox (точнее редактируете на основе стандартного). Там можно все визуально настроить как на обычной форме. Указываете этот StyleBook форме.

    Имена объектов указываете в StyleName каждого объекта.

    Чтобы менять картинку просто указывая image index для ListBox Item'a (vItem.ImageIndex ) картинка TGlyph  должна иметь имя 'glyphstyle'.

    Далее обращаетесь к ним по StyleName именам так:

    vItem.Text := vCampaign.Name;
    vItem.StylesData['descript'] := fCore.Settings.LoadCampaignDescr(vCampaign.Name);
    vItem.StylesData['details'] := '';
    
    vItem.ImageIndex := 3;

    В моем случае descript и details - это TText.

    А вот так работать можно с любыми контролами:

    vItem.NeedStyleLookup;
    vItem.ApplyStyleLookup; // without this, FindStyleResource will return nil
    
    vSwitch := vItem.FindStyleResource('switch') as TSwitch;
    Assert(vSwitch <> nil);
    vSwitch.IsChecked := vCampaign.Enable;
    vSwitch.OnClick := DoOnClickCampaignSwitch;

     

    ну и на всякий случай: 

    vItem := TListBoxItem.Create(nil);
    vItem.Parent:= Listbox;
    Listbox.AddObject(vItem);
    vItem.StyleLookup := 'CampaignItem';


     

  10. изменил порядок - и поплыло все. 

    @krapotkin

    Понятное дело что придется это учитывать. Но в моем случае это очень даже оправдано.

     

    а вот несколько раз вызывать FindDrawable в процедуре - это неправильно. сохраняйте ссылку и пользуйтесь ей

    У меня 15 элементов на один Item.  По другому никак, нужно вызвать 15 раз FindDrawable (+ OnUpdate срабатывает не один раз), а также этот метод будет вызываться при заполнении данных еще 15 раз. И в каждом FindDrawable прямым перебором перебираются 15 элементов и сравниваются строки каждого объекта, и это для каждого Item'a в ListView. Если использовать индексы это в несколько раз повысит скорость работы с ListView. 

    Если я буду еще и кэшировать объекты в отдельных списках, то я просто запутаю код программы. Гораздо проще и прозрачнее использовать индексы.

    Ведь для удобства можно ввести именованные константы индексы - и если измениться порядок следования - то это нужно изменить всего в одном месте (в константах).

  11. Есть еще один альтернативный способ доступа к объектам.

    Вместо AItem.Objects.FindDrawable('TextButton16')  можно обращаться по индексам. Это гораздо быстрее. Т.к. не нужно перебирать все объекты и сравнивать их строковые имена. К примеру в моем случае их аж 16, и у каждого есть имя. Каждое строковое имя нужно перебрать и сравнить с искомым. При этом в OnUpdateObjects это может делаться несколько раз на каждый List item.

    Сделать это можно так:

     

    aItem.View.ViewList[x]

    Напр:

    aItem.View.ViewList[10].Height := 30;

    Список можно посмотреть так: 

    В инспекторе объектов, найдите ListView, в нем Item. Выберите его, и в списке свойств нажмите Objects- это и будет полные список объектов. Начинается он с нуля. Отсчитаете нужный, и можно работать с ним.

    Upd:

    Также можно  изменять объекты TListItem'a по индексу вместо Data['name']. Там тоже используется FindDrawable.

    Для этого сначала нужно добавить один раз значение через Data для любого из объектов чтобы создать нужны структуры (обычно для первого Object'a ), а затем уже заполнять по индексу остальные Objects в любой последовательности (не обязательно подряд).

     vItem.Data['T']  := 'Text'  // Data['T'] - это текст ListItem, так он стандартно обозначен

    Дальше уже добавляем текст в объекты через индекс: 

    (vItem.View.Drawables[5] as TListItemText).Text := 'Text 5';  

    (vItem.View.Drawables[1] as TListItemText).Text := 'Text 2';  

     

  12. Что отладчик пишет? Вы пробовали запускать под отладчиком (F9)?

    Ставьте точки останова, смотрите куда доходит. Проблема где-то в вашем коде.

    Отключите все формы кроме главной в dpr (Project > View Source) (вообще по хорошему, так и должно быть по умолчанию, формы создаются только когда нужно).

    Попробуйте полностью удалить приложение на телефоне, и установить с нуля.

  13. Ребята, если вам нужна кнопка с картинкой на ListView, то это можно сделать скомбинировав  картинку  с кнопкой :) . 

    Сначала добавляете TTextButtonObjectAppearance, затем TImageObjectAppearance и устанавливаете картинку поверх кнопки.

     

    Чтобы определить по какому элементу Item'a кликнул юзер: 

     

    procedure TForm1.ListView1ItemClickEx(const Sender: TObject; ItemIndex: Integer; const LocalClickPos: TPointF; const ItemObject: TListItemDrawable);
    begin
      if ItemObject = nil then exit;
    
      ShowMessage('Name: ' + ItemObject.Name + sLineBreak + 'Text: ' + (ItemObject as TListItemText).Text);
    end;


     

  14. @Barbanel

    Никаких проблем c этим кодом не было с 4 и 5 Android. На 6 не проверял. Точно такой же код пишет народ на Java там тоже никаких проблем по этому поводу не писали.

    Чтобы убедиться что проблема точно не в паузе, попробуйте установить sleep на 10- 20 секунд. 

    Может вы не закрываете курсор после какого то из запросов раньше?

    да еще момент, в Action TakePhotoFromCameraAction нужно установить свойство NeedSaveToAlbum := true  . Возможно это ключевой момент в вашем вопросе (т.к. на некоторых телефонах (привет HTC) фотки сохраняются в галерею даже если NeedSaveToAlbum = false, это уже баг конкретной модификации Андроида).

×
×
  • Создать...