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

Brovin Yaroslav

Администраторы
  • Постов

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

  • Посещение

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

    390

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

  1. Чтобы добавить любое изображение в системную галерею изображений Андроида нужно:

    1. Получить универсальный URI к вашей картинке GetImageUri. Для этого сохраняем изображение (если изображение находится в памяти устройства, а не в файловой системе) в кэш приложения.
    2. Формируем намерение JIntent, что хотим добавить изображение. Задаем URI к картинке и делаем широковещательный запрос на все приложения, которые могут обработать наш запрос.
    // Сохранение изображения в кэш приложения и извлечение Url к этому файлу
    function GetImageUri(ABitmap: TBitmap): Jnet_Uri;
    var
      ImageFile: JFile;
      ImageUri: Jnet_Uri;
      FileNameTemp: JString;
      FileNameExt: JString;
    begin
      FileNameTemp := StringToJString('temp');
      FileNameExt := StringToJString('.jpg');
      try
        ImageFile := TJFile.JavaClass.createTempFile(FileNameTemp, FileNameExt);
        ImageUri := TJnet_Uri.JavaClass.fromFile(ImageFile);
        ABitmap.SaveToFile(JStringToString(ImageFile.getAbsolutePath));
      finally
        Result := ImageUri;
      end;
    end;
    
    procedure AddPhotoToGallery(const APhoto: TBitmap);
    var
      Intent: JIntent;
    begin
      Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_MEDIA_SCANNER_SCAN_FILE);
      Intent.setData(GetImageUri(APhoto));
      SharedActivity.sendBroadcast(Intent);
    end;
    
  2. Чтобы ответить самостоятельно на этот вопрос, нужно понимать следующие факты:

    1. XCode - среда разработки программного обеспечения под OSX и iOS (Wiki).
    2. XCode позволяет использовать разные компиляторы в том числе компиляторы известного проекта FreePascal под Delphi
    3. ARM компилятор Delphi доступен только для Win32/Win64 платформы.
    4. Язык Delphi можно использовать в XCode, но только в совокупности с компилятором от FreePascal. Кстати, такой вариант был и успешно работал в RAD Studio XE2, поскольку на тот момент Embarcadero еще не имела собственного компилятора под ARM.
    5. FreePascal имеет свой набор библиотек, и не смотря на то, что есть общие интерфейсы с Delphi, ваш код вряд ли будет совместим с библиотеками от FreePascal.
    6. Не смотря на то, что можно использовать компилятор от FreePascal, вряд ли удастся за адекватное время перевести FireMonkey на использование библиотек от FreePascal. Так как после появления собственного ARM компилятора из FireMonkey была убрана поддержка FreePascal.

    Отсюда можно посчитать, что для небольшого проекта, эта затея гиблая и частично бессмысленная. Так как сборка одного и того же кода разными компиляторами вряд ли радикально улучшит качество кода проекта.

     

    Если же речь идет о переписи исходников проекта с Delphi на Objective C, то вам следует вначале изучить язык Objective C и затем переписывать весь проект на него.

  3. Например так для RGB:

    var
      Color: TColor;
    begin
      TColorRec(Color).R := 123;
      TColorRec(Color).G := 113;
      TColorRec(Color).B := 13;
      Rectangle1.Fill.Color := Color;
    end;
    

    Или так для ARGB:

    var
      Color: TAlphaColor;
    begin
      TAlphaColorRec(Color).R := 123;
      TAlphaColorRec(Color).G := 113;
      TAlphaColorRec(Color).B := 13;
      TAlphaColorRec(Color).A := 126;
      Rectangle1.Fill.Color := Color;
    end;
    

    Update 1 (2014.06.25): В RAD Studio XE6 появился более удобный способ через использование конструктора типа TAlphaColorF:

    uses
      System.UITypes;
    
    var
      Color: TAlphaColor  
    begin
      Color := TAlphaColorF.Create(123 / 255, 113 / 255, 13 / 255, 126 / 255).ToAlphaColor;
    end;
    
  4. Код подправил. Строчка с 

    Instance := Button1;
    

    лишняя. 

     

    Да, по коду ищутся дочерние контролы. В коде не видно, но это дочерние узлы формы. В вашем случае нужно код исправить на рекурсию, чтобы пробежаться не только по контролам первого уровня, но и по всем узлам дерева контролов до листьев.

  5. Добрый день,

     

    В RAD Studio XE5 для поддержки возможности массово менять настройки текста для любых контролов был введен специальный интерфейс ITextSettings. Каждый контрол, который поддерживает настройку параметров текста, реализует этот интерфейс. Поэтому, чтобы массово поменять настройки текста можно использовать, например, следующий код (Delphi, он легко переводится на C++). Этот код Для всех наследников, которые не используют размер шрифта из стиля, задает размер шрифта:

    var
      Settings: ITextSettings;
      Instance: TComponent;
      I: Integer;
    begin
      for I := 0 to ChildrenCount - 1 do
      begin
        Instance := Children[I];
        if IInterface(Instance).QueryInterface(ITextSettings, Settings) = S_OK then
        begin
          // using ITextSettings methods and properties:
          //   TextSettings: TTextSettings,
          //   DefaultTextSettings,
          //   StyledSettings
          // to change properties of text objects
          Settings.TextSettings.BeginUpdate;
          try
            Settings.TextSettings.Font.Size := 18;
            if TStyledSetting.ssSize in Settings.StyledSettings then
              Settings.StyledSettings := Settings.StyledSettings - [TStyledSetting.ssSize]
                // show Font.Size := 18  
            else
              Settings.StyledSettings := Settings.StyledSettings + [TStyledSetting.ssSize];
                // restore showing Font.Size loaded from a style  
          finally
            Settings.TextSettings.EndUpdate;
          end;
        end;
      end;
    end;
    
  6. Добрый день,

    • В событии MouseDown у TListBoxItem ищем в стиле итема объект изображения. Для итема картинка имеет название 'icon'.
    • Определяем координаты мыши в координатах формы (Абсолютные координаты). На случай отступов и произвольного размещения изображения.
    • Конвертируем абсолютные координаты в локальные координаты изображения.
    • Если картинка содержит координаты мыши, значит нажали на картинку.

    Delphi:

    procedure TForm6.ListBoxItem1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
    var
      Item: TListBoxItem;
      StyleObject: TFmxObject;
      StyleIcon: TControl;
      LocalMousePos: TPointF;
      AbsoluteMousePos: TPointF;
    begin
      if Sender is TListBoxItem then
      begin
        Item := TListBoxItem(Sender);
        LocalMousePos := TPointF.Create(X, Y);
        AbsoluteMousePos := Item.LocalToAbsolute(LocalMousePos);
        // Ищем объект стиля - картинка. Лучше закешировать один раз, избежав постоянный поиск картинки 
        StyleObject := Item.FindStyleResource('icon');
        if (StyleObject <> nil) and (StyleObject is TControl) then
        begin
          StyleIcon := TControl(StyleObject);
          // Координаты в локальной системе координат картинки
          LocalMousePos := StyleIcon.AbsoluteToLocal(AbsoluteMousePos);
          if StyleIcon.LocalRect.Contains(LocalMousePos) then
            ShowMessage('Click on Image');
        end;
      end;
    end;
    

    Builder C++:

    void __fastcall TForm4::ListBoxItem1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, float X, float Y)
    {
    	TListBoxItem *item = dynamic_cast<TListBoxItem*>(Sender);
    	if (item != 0){
    		TPointF localMousePos(X, Y);
    		TPointF absoluteMousePos = item->LocalToAbsolute(localMousePos);
    		// Ищем объект стиля - картинка. Лучше закешировать один раз, избежав постоянный поиск картинки
    		TFmxObject *styleObject;
    		styleObject = item->FindStyleResource("icon");
    		if (styleObject != NULL) {
    			TControl *styleIcon = dynamic_cast<TControl*>(styleObject);
    
    			// Координаты в локальной системе координат картинки
    			localMousePos = styleIcon->AbsoluteToLocal(absoluteMousePos);
    			if (styleIcon->LocalRect.Contains(localMousePos))
    				ShowMessage("Click on Image");
    		}
    	}
    }
    
  7. Добрый день,

     

    Теперь он в качестве параметра принимает объект другого класса, а именно интерфейса IIdTextEncoding, который описывает основные методы по работе с потоком.

     

    Естественно, что этот интерфейс вам не нужно реализовывать, а нужно найти его реализацию для UTF8 кодировки. 

     

    Собственно смотрим в IdGlobal.pas и видим там глобальные процедуры по получению нужных реализаций в требуемых кодировках:

      IdTextEncodingType = (encIndyDefault, encOSDefault, enc8Bit, encASCII, encUTF16BE, encUTF16LE, encUTF7, encUTF8);
    
      function IndyTextEncoding(AType: IdTextEncodingType): IIdTextEncoding; overload;
      function IndyTextEncoding(ACodepage: Word): IIdTextEncoding; overload;
      function IndyTextEncoding(const ACharSet: String): IIdTextEncoding; overload;
      {$IFDEF DOTNET}
      function IndyTextEncoding(AEncoding: System.Text.Encoding): IIdTextEncoding; overload;
      {$ENDIF}
      {$IFDEF HAS_TEncoding}
      function IndyTextEncoding(AEncoding: TEncoding): IIdTextEncoding; overload;
      {$ENDIF}
    
      function IndyTextEncoding_Default: IIdTextEncoding;
      function IndyTextEncoding_OSDefault: IIdTextEncoding;
      function IndyTextEncoding_8Bit: IIdTextEncoding;
      function IndyTextEncoding_ASCII: IIdTextEncoding;
      function IndyTextEncoding_UTF16BE: IIdTextEncoding;
      function IndyTextEncoding_UTF16LE: IIdTextEncoding;
      function IndyTextEncoding_UTF7: IIdTextEncoding;
      function IndyTextEncoding_UTF8: IIdTextEncoding;
    

    Тут либо используем конкретный метод  IndyTextEncoding_UTF8, либо же используем вариант через:

    IndyTextEncoding(IdTextEncodingType.encUTF8)
    
  8. OXML - это новая библиотека по работе с XML для Delphi и Lazarus, разработанная в конце 2013 года.

    Целью OXML является быть универсальной и быстрейшей XML библиотекой для языка Паскаль.

    Основные особенности OXML являются:

    1. Парсер SAX
    2. Реализация DOM 
    3. Прямое чтение /запись XML файлов 
    4. Полная совместимость при работе с TXMLDocument (XmlIntf.TXMLDocument)

     

    Автор: Software Solution Ondřej Pokorný

    Тип лицензии: Open Source

    Ссылка: http://www.kluug.net/oxml.php

    Скачать: SourceForge

     

    Library design

    • Use the same XML library for all your Pascal projects including:
      1. Delphi for Win32, Win64 and OSX (Delphi 6 and newer).
      2. Delphi ARC/NEXTGEN for iOS and Android (Delphi XE4 and newer).
      3. Lazarus on Win32, Win64, Linux, OSX (Lazarus 1.0 and newer).
      4. Corresponding C++Builder compilers (not tested though).
    • Native pascal object oriented code.
    • No external dll libraries are required.
    • No dependency on a visual library like VCL, LCL or FMX.
    • Full unicode support even for D6-D2007.
    • Powerful XPath engine.
    • Faster than everything else on all platforms thanks to various optimizations.
    • OXml is able to read and write invalid XML documents and correct errors in them (if wanted). If not wanted, OXml throws an exception when you are trying to read/write an invalid XML document.
    • Supports all on the platform available encodings (UTF-16, UTF-8, single-byte ISO, WIN, KOI8...) by all parsers automatically. That means that the encoding is read and set from the <?xml encoding="" ?> tag during both reading and writing.
    Readers and writers included in OXml
    OXml features 4 classes for working with XML documents:
    1. TXMLWriter (OXmlReadWrite.pas): Basic XML writer. All other classes use it.
      Use it directly if performance is crucial for you.
    2. TXMLReader (OXmlReadWrite.pas): Basic XML reader. All other classes use it.
      Don't use it directly. If performance is crucial for you, use SAX which has the same performance but is much more comfortable to work with.
    3. TSAXParser (OXmlSAX.pas): Event-based parser according to the SAX specification.
      Anonymous methods are supported for modern Delphi versions, too. It's very fast and needs practically no memory.
    4. IXMLDocument (OXmlPDOM.pas): Record-based DOM according to the W3C DOM Level 1 specification. (Not strict - some small changes have been made to maximize performance).
      The fastest and most memory-friendly DOM for Pascal.
    5. TXMLSeqParser (OXmlSeq.pas): Sequential DOM parser based on OXmlPDOM.pas.
      Read huge XML files into the DOM sequentionally. This method combines DOM capabilities without the need to load the whole document at once.
      OXmlSeq is even a little bit faster than OXmlPDOM.
    6. sOXmlDOMVendor (OXmlDOMVendor.pas): fastest DOM vendor for Delphi's own TXMLDocument.
      Use TXMLDocument(MyXmlDoc).DOMVendor := GetDOMVendor(sOXmlDOMVendor) if you want to use Delphi's default TXMLDocument with the fastest and cross-platform vendor.
    What are the differences between OXmlPDOM and OmniXML / MS XML?
    1. In general OXmlPDOM is very close to both implementations. They share the same functions and properties.
    2. OmniXML and MS XML are interfaced-based. That means that nodes are created one-by-one and when they are not referenced any more, they are automatically destroyed. 
      OXmlPDOM is record-based. Nodes are created by groups of 1024 items, which offers stunning performance. They are automatically destroyed only when the owner XML document is destroyed. Therefore such functions do not free memory used by a node:
      • TXMLNode.RemoveChild()
      • TXMLNode.ReplaceChild()
      When using OXmlPDOM you should call TXMLNode.DeleteChild(), TXMLNode.DeleteAttribute() or TXMLNode.DeleteSelf in order to be sure the node memory is marked as free and can be reused again.
    3. The nodes are of PXMLNode type - pointer to TXMLNode structure. Strictly speaking, PXMLNode nodes have to be dereferenced to TXMLNode when used but Delphi does this dereferencing for you, so you can easily use: XML.DocumentElement.AddChild('child');
      If you use FPC/Lazarus in Delphi mode ({$MODE DELPHI}), the nodes get dereferenced too. But if you use FPC/Lazarus in default mode, you have to dereference it manually with the "^" operator: XML.DocumentElement^.AddChild('child');
    4. OXmlPDOM does not store child nodes and attributes in AttributeNodes and ChildNodes lists.
      That means that the lists are created only when they are needed by the user. AttributeNodes and ChildNodes are not typical TList descendants but they are doubly linked lists with fast index iteration and count function support.
  9. Компонент проигрывания всех современных форматов Видео/Аудио/потоков для Андроида.

     

    Автор: Flash AV Software Corp.

    Тип лицензии: коммерческая

    Ссылка: http://www.flashavconverter.com/content/vlc-player-android-10

    Скачать Trial: ZIP

     

    VLC Player For Android is a video player component based on VLC to decode and play video/ audio. 

    • Support playing all the video / audio / Network Stream that can be decoded by VLC.
    • Support Hardware acceleration.
    • Provide stop , pause , resume, step forward, seek operations .
    • Volume control.

    The main difference is VLC Player has better performance  but can only playback video with build-in Java Android GUI. The video playback GUI can not use FMX GUI controls.

  10. Если такое поведение наблюдается, то его можно обойти, вручную определив момент нажатия на картинку.

    1. Создаем TListBoxItem
    2. Добавляем в него TImage и выставляем HitTest = False.
    3. Переопределяем событие итема OnMouseUp. Внутри метода определяем оторвали палец от экрана на текущей картинке или нет. Если да, то клик был по картинке.
    procedure TForm6.ListBoxItem2MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
    begin
      if Image1.ParentedRect.Contains(TPointF.Create(X, Y)) then
        ShowMessage('Click on Image');
    end;
    

    P.S. Описанное вами поведение мне воспроизвести не удалось. Однако, если у вас по каким-либо причинам оно воспроизводится, используйте мои рекомендации выше.

  11. Мне кажется лучшим вариантом решения будет такой вариант:

    1. Используем обычный ЛистБокс с картинкой. Можно использовать обычный тип TListBoxItem со стилем 'listboxitembottomdetail', который содержит и текст описания и картинку.
    2. Далее вставляем в итем картинку через TListBoxItem.ItemData.Bitmap.
    3. В событии OnMouseDown у итема определяем положение пальца и если положение совпадает с положением картинки, то открываем отдельную страницу с браузером растянутым на весь экран. Об этом решении написано тут: Как определить положение картинки в TListBoxItem?

    Не имеет смысла встраивать маленький браузер, потому что на нем все равно путного ничего не увидишь. Поэтому обычно, при нажатии на видео открывается полноэкранный вариант проигрывателя. В вашем случае, основанного на TWebBrowser.

  12. В таком случае у вас точно будет тормозить скроллинг и все приложение. Так как создание и удержание даже 30 экземпляров браузера это тяжелая задача для телефона.

    Вначале изучите, как работает стандартное приложение YouTube или Вконтакте. И обратите свое внимание на то, когда и в какой момент воспроизводится видео. Отчетливо видно, что браузер имеет смысл создавать только в одном экземпляре и только в тот момент времени, когда пользователь непосредственно выявил свое желание просмотреть видео. Это является примером грамотного подхода к разработке.

     

    P.S. Я сделал новый раздел на форуме "Советы по разработке -> Мобильная разработка", в котором вы можете задавать свои вопросы для получения советов о том, как лучше спроектировать свое приложение, чтобы в дальнейшем не было проблем со скоростью и сопровождением.

  13. Использую такой же код по нажатию на кнопку:

    procedure TForm5.Button1Click(Sender: TObject);
    var
      WebBrowser: TWebBrowser;
    begin
      WebBrowser := TWebBrowser.Create(Self);
      WebBrowser.Parent := Self;
      WebBrowser.Position.X := 3;
      WebBrowser.Position.Y := 3;
      WebBrowser.Width := 314;
      WebBrowser.Height := 177;
      WebBrowser.Navigate('http://yandex.ru/');
    end;
    

    Браузер успешно создается в нужном месте на форме и страница открывается. Проверил на iOS.

    1. Неправильная выбранная частота отрисовки. Проблема вашего примера в том, что вы используете совершенно не нужную частоту обновления кадра - 100 кадров в секунду. Частота съёмки в современном телевидении составляет порядка 24-30 кадра в секунду (Википедия). При большей частоте кадра человеческий глаз не сможет физически отличить 24 кадра от например 100 кадров в секунду. Поэтому в вашем случае достаточно для таймера использовать например 30-40 милисекунд, увеличив скорость изменения картинки в 3-4 раза. После этих изменений, я не вижу подтормаживаний. Как минимум этим вы увеличите скорость в 3-4 раза.
    2. Не нужно использовать изображения больше, чем того нужно, которые потом автоматически программным путем каждый раз сжимаются в несколько раз. Это опять же сказывается на производительности вашего приложения. Например в вашем случае, вы используете картинку размером 300х400, а сами в конечном итоге используете изображения только размером 50х50.

    P.S. FireMonkey не позиционируется, как игровой движок. Поэтому, если вы приняли решение все-таки сделать игру, игнорируя рекомендации, то вам придется очень детально обращать свое внимание на вопросы производительности: грамотное использование ресурсов, движение объектов, использования картинок и другие вопросы.

  14. В вашем случае вы создаете 5 изображений 50х50. Но при этом на самом деле туда копируете 5 изображений 300х400. Для использования в качестве спрайтов при частом обновлении (10 миллисекунд) такой подход не допустим. Попробуйте уменьшить размер изображения до реально используемого.

  15. Для хранения настроек приложения можно использовать обычный Ini файл, который работает на всех платформах одинаково.

    1. TIniFile - класс для работы с ini файлами.
    2. Руководство по использованию TIniFile: Using TIniFile and TMemIniFile
×
×
  • Создать...