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

Brovin Yaroslav

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

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

  • Посещение

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

    390

Ответы сообщества

  1. Пост Brovin Yaroslav - сообщение в Куда делся TJSONObject в XE6? был отмечен как ответ   
    TJSONObject был перемещен в другое место из Data.DBXJSON в System.JSON. Подробнее тут: What's New in Delphi and C++Builder XE6 Работать так же, как и раньше. Просто изменить название подключаемого модуля на System.JSON.
  2. Пост Brovin Yaroslav - сообщение в Как узнать, что поддерживается антиалиасинг на устройстве на базе Андроид? был отмечен как ответ   
    Проверить можно, установив программу OpenGL Extensions Viewer (Бесплатная) и посмотреть.
    Обратить внимание на наличие опции: "GL_EXT_multisampled_render_to_texture"

  3. Пост Brovin Yaroslav - сообщение в Как включить антиалиасинг на Андроиде? был отмечен как ответ   
    По умолчанию антиалиасинг отключен на Андроиде. За управление этим эффектом отвечает свойство TForm.Quality. Оно имеет три режима:
    HighQuality - Качество отображения в приоритет. Поддержка антиалиасинга HighPerformance - Производительность в приоритете. Отсутствие антиалиасинга. SystemDefault - По умолчанию. Для андроида равен HighPerformance. В вашем случае для формы нужно установить 
    Quality = HighQuality Важно знать
    Антиалиасинг очень дорогостоящая операция, по этому по умолчанию она отключена на мобильных платформах. Так же антиалиасинг должен поддерживаться самим устройством (Поддержка Мультисэплинга).  Если устройство аппаратно не поддерживает мультисэмплинг, то антиалиасинга не будет.
  4. Пост Brovin Yaroslav - сообщение в Как узнать о том, что WebBrowser завершил загрузку контента? был отмечен как ответ   
    WebBrowser использует под андроидом связку нативного браузера WebView и WebClient для получения уведомлений о состоянии загрузки страницы.
    Поэтому в FMX мы получаем событие окончания загрузки страницы через: TWebBrowser.OnDidFinishLoad, который в свою очередь получается из WebViewClient.onPageFinished. Если это событие не дает своего эффекта, то решения нету из-за отсутствия поддержки со стороны Google.
    Согласно официальной документации гугла, это событие вызывается, когда полностью загружен главный фрейм страницы, исключая не загруженные изображения. Поэтому это событие не поможет. Согласно этой же документации нету события, который бы позволил определить момент, когда загружены и все внутренних встроенные страницы. Увы.
  5. Пост Brovin Yaroslav - сообщение в Как поменять два ListBoxItem’а между собой, используя анимацию? был отмечен как ответ   
    Вообще неправильно пытаться менять позицию итемов в TListBox, поскольку сам контрол TListBox отвечает за выравнивание и расстановку своих итемов.  Вы же пытаетесь пойти против работы TListBox и по своему выравнивать итемы. В этом случае вам нужно создать наследника от TListBox и переопределить алгоритм выравнивания элементов.
  6. Пост Brovin Yaroslav - сообщение в Как растянуть картинку на весь TImage? Аналог Stretch. был отмечен как ответ   
    А чем не подходит аналог того же самого свойства?
    TImage.WrapMode = wmStretch;
  7. Пост Brovin Yaroslav - сообщение в У меня перестает работать фокус после смены фокуса с TWebBrowser на TEdit был отмечен как ответ   
    Такое поведение действительно было в XE5. В XE6 его исправили.
  8. Пост Brovin Yaroslav - сообщение в Пользоваться Free или DisposeOf? был отмечен как ответ   
    Собственно ответ был дан уже давно тут: Как правильно удалять контролы в RunTime?
    Единственное новое дополнение - это то, что метод Free под мобильными платформами дополнительно очищает указатель на объект.
     
    То есть:
    var A: TObject; begin A := TObject.Create; A.Free; // В этом месте A = nil на мобильных платформах. // На настольных платформах: A указывает на мусор end;
  9. Пост Brovin Yaroslav - сообщение в [iOS] Как сделать цветную обводку кнопки в iOS? был отмечен как ответ   
    Теперь в RAD Studio XE6 для iOS и Андроид появилась поддержка Tint эффекта, который позволяет прямо в дизайнере менять цвет фона, обводки и заливки иконок кнопки.
     
    Этот эффект позволяет легко менять оттенок фона и контура кнопки. Примеры для Андроид и iOS изображены ниже.
    Смена фона кнопки на Android:

    Быстрая смена заливки кнопок с иконками на iOS:

    Быстрая смена контура кнопки, если он поддерживается стилем:

     
    Обратите внимание, что поддержка данного эффекта зависит от стиля. Если стиль поддерживает его, то в дизайнере появятся свойства редактирования цвета. Если стиль не поддерживает, то свойства Tint будут скрыты.
  10. Пост Brovin Yaroslav - сообщение в Компонент рекламы был отмечен как ответ   
    В RAD Studio XE6 появился новый компонент TBannerAd, который позволяет встраивать контекстную рекламу в ваше приложение. Компонент поддерживает все мобильные платформы (iOS, Android).
     
    Компонент добавлен в раздел "Additional" панели палитры инструментов.
  11. Пост Brovin Yaroslav - сообщение в Редактирование стиля, как добавить "TStyleObject", "TActiveStyleObject" и т.п.? был отмечен как ответ   
    По умолчанию эти объекты стиля и другие не зарегистрированы в палитре инструментов.
    Эти объекты используются только в стилях для:
    Упрощение создания стиля за счет композиции контролов для достижения наиболее часто используемых функций (смена изображений по триггеру в зависимости от состояния контрола  - кнопка с тремя состояниями, Текст с тенью) Увеличения производительности работы стиля за счет композиции контролов. Уменьшение размера стиля за счет повторного использования одного исходного изображения в однотипных контролах (TButton, TSpeedButton и тд). То есть вместо загрузки по отдельности каждого изображения в стиль каждого контрола, можно использовать изображения по ссылке. Чтобы их использовать, нужно их зарегистрировать в среде IDE RAD Studio.
    Это делает вот этот пакет: 
    RAD Studio XE5 - FMX Style Objects.zip RAD Studio XE6 - FMX Style Objects (XE6).zip После установки пакета в палитре инструментов появится вкладка "Style Object", в которой будут находится все служебные стилевые объекты среды RAD Studio XE5.
     
    Список добавляемых стилевых объектов: 
    TStyleObject - Использование изображения по ссылке на оригинал и области в этом изображении. Не загружает повторно объект. TSubImage - Использование изображения по ссылке на оригинал и области в этом изображении. Не загружает повторно объект. TActiveStyleObject - Объект для смены одного изображения на другое с указанным типом анимации и указанным триггером. TTabStyleObject - специальный объект для быстрого создания стиля вкладки TTabControl TCheckStyleObject - специальный упрощенный объект для создания стиля TCheckBox TButtonStyleObject - упрощенный объект стиля кнопки с поддержкой загрузки отдельных изображений на каждое состоянии кнопки (нормальное, фокус, под мышкой, нажатое) TSystemButtonObject - стиль системной кнопки. То же, что и TButtonStyleObject, только с дополнительным состоянием - неактивная кнопка TStyleTextObject - объект для быстрого создания стиля текст с тенью. TStyleTextAnimation - объект анимации для смены цвета и тени текста  TActiveStyleTextObject - объект стиля для создания текста с тенью и переключению цвета текста и тени на другой по анимации и триггеру. TTabStyleTextObject - объект стиля для создания вкладки с текстом для TTabControl. TButtonStyleTextObject - объект стиля для создания стиля кнопки с текстом. TActiveOpacityObject - объект для смены прозрачности контрола. TBrushObject - объект хранящий кисть TBrush TBitmapObject - объект хранящий изображение TBitmap TFontObject - хранение шрифта TFont TPathObject - хранение SVG пути TPath TColorObject - хранение цвета TAlphaColor
  12. Пост Brovin Yaroslav - сообщение в Как запретить ввод с клавиатуры? был отмечен как ответ   
    Добрый день,
     
    Есть несколько способов реализовать это:
    1. Свойство TEdit.ReadOnly. Когда появляется Layout, мы устанавливаем свойство ReadOnly в True
    Edit.ReadOnly := True По скрытию Layout, обратно сбрасываем свойство ReadOnly:
    Edit.ReadOnly := False Дополнительно можно скрыть каретку в TEdit путем сброса фокуса:
    Edit.ResetFocus; Такой способ хорош, когда нужно запретить ввод только в контролы, построенные на базе TEdit. Потому что не все контролы имеют свойство ReadOnly.
     
    2. Вручную поставить фильтр на вводимые символы в любой контрол. Для этого определяем обработчик для TControl.OnKeyDown, который вещаем на все контролы, в которые вы хотите запретить ввод. В обработчике сбрасываем коды символов, если текущий режим не разрешает ввод. В моем примере я обозначил это переменной InputAllowed
    procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState); begin if not InputAllowed then begin Key := 0; KeyChar := #0; end; end; Этот способ лучше тем, что этот обработчик можно повесить на любой контрол и тем самым разом полностью заблокировать ввод символов. Однако, если вам нужно в некоторых контролах выполнять дополнительные действия, то придется создавать отдельные обработчики. Все зависит от вашей задачи.
     
    Более простых решений в одну-две строчки нет.
  13. Пост Brovin Yaroslav - сообщение в Создание стиля для своего компонента был отмечен как ответ   
    Это устаревшее руководство, так как дизайнер стилей уже давно поменялся.
     
    Но все же, Под "Create Style Panel" панелью понимается в данном случае панель под деревом объектов стиля. К сожалению у меня сейчас нету вашей версии, чтобы показать вам ее, но она находится строго под деревом. Туда бросаете компонент, который будет взят за основу. И после он появится в дереве стилей. 

     
    В новых версия среды, начиная с XE4, поменялся дизайнер стилей. И чтобы создать новый стиль, нужно перетащить контрол с палитры компонентов "Tool Palette" в "Structure". В новых версия также все создание стиля идет на панели Structure

  14. Пост Brovin Yaroslav - сообщение в Возможно ли создать свои тригеры для запуска анимации? был отмечен как ответ   
    Возможно. Для этого нужно две вещи:
    Иметь опубликованное свойство триггера (published) Инициировать запуск триггера можно командами: procedure StartTriggerAnimation(const AInstance: TFmxObject; const ATrigger: string); procedure StartTriggerAnimationWait(const AInstance: TFmxObject; const ATrigger: string); procedure ApplyTriggerEffect(const AInstance: TFmxObject; const ATrigger: string); Метод выбирается в зависимости от того, что должен триггер стартовать: анимацию или эффекты переходов (Transition Effects).
  15. Пост Brovin Yaroslav - сообщение в [Отклонение] Приложения с SQLite не запускаются на Android 2.3.6 был отмечен как ответ   
    Проверил в  XE6 бета ошибка на сниппете не воспроизводится. Видимо QC уже исправили.
  16. Пост Brovin Yaroslav - сообщение в [TTabControl] Красивое 3D переключение вкладок в TabControl был отмечен как ответ   
    Можно сделать так:
    Делаем поворот TTabControl на от 0 до 90 градусов, чтобы он повернулся к пользователю ребром. По окончании первой анимации меняем активную вкладку в TTabControl. Делаем поворот TTabControl еще на 90 градусов от 270 до 360. В итоге TTabControl поворачивается к нам уже новой вкладкой.  Видео эффекта в действии: 

     
    Проект: TTabControl_3DRotationDemo.zip
  17. Пост Brovin Yaroslav - сообщение в В моем случае при использовании 3D формы и ряда TLayer3D не удается нажать на 2D контрол был отмечен как ответ   
    Рабочее решение, сбросить HitTest в False для слоев. Они перехватывают события. Для 3D объектов BringToFront и BringToBack не работают так, как вы ожидаете. Поскольку у 3D объектов это положение зависит от точки наблюдения. Вместо этого в вашем случае нужно использовать ось Z. Зачем для 2D интерфейса использовать 3D форму?
     
    Это не оправдано. Отмечу, что выбор использования 2D или 3D формы зависит от вашего варианта использования. Например:
    2D форма. Когда преобладающая часть контролов - это 2D контролы. Чтобы использовать 3D объекты, используйте встроенные TViewPort3D. Если нужны 3D эффекты в редких случаях, то проще на момент создания эффекта добавить в корень формы TViewPort3D с TLayer3D, затем перенести туда все ваши контролы. выполнить эффекты и восстановить обратно. В этом случае не будет и проблем с нажатием в 3D форме.  3D форма. Все тоже, что и в 2D форме только со знаком минус.
  18. Пост Brovin Yaroslav - сообщение в Можно ли использовать один TFloatAnimation для двух объектов? был отмечен как ответ   
    Нет
    Можно использовать два TFloatAnimation для двух объектов. Таймер использовать не надо. Один аниматор анимирует одной свойство у одного объекта (родительского)
  19. Пост Brovin Yaroslav - сообщение в Как изменить стиль по умолчанию для андроида? был отмечен как ответ   
    Если задача стоит просто изменить стандартный платформенный стиль. То, чтобы измененный стиль не занимал дополнительное место в приложении, нужно им заменить стандартный.
     
    Я писал давно статью на эту тему тут: FMX 2.0. Глобальная замена платформенного стиля по умолчанию без TStyleBook
     
    Идея простая, заменить ресурс стандартного стиля на ваш.
     
    Дополнение для названия ресурсов в приложении. Вначале указано название ресурса в приложении, затем платформа
    iphonestyle - iPhone iOS < 7.0  ipadstyle -  iPad iOS < 7.0 iphonepadstyle_Modern - iOS >= 7.0 androidstyle - Android win7style -  WIndows 7 win8style - Windows 8 lionstyle - OSX Если же вы создаете новые стили (кастомный стиль итемов и тд), то их нужно грузить обычным способом через стиль бук. И поскольку они новые, ваши, то они включаются в ресурсы формы и увеличивают размер приложения.
  20. Пост Brovin Yaroslav - сообщение в Можно ли расширить стандартные хелперы? был отмечен как ответ   
    Добрый день.
     
    Увы нет. Для каждого типа можно написать только один хелпер, поэтому если вы определяете новый, то он заменяет существующий.
     
    На текущий момент придется копировать все реализации. Либо управлять видимостью хелперов через скоп. То есть вы можете иметь свой хелпер, и использовать его локально в своих юнитах. А в тех юнитах, где нужно использовать стандартные хелперы использовать их.
     
    Ссылка на документацию: Class and Record Helpers (Delphi)
     
     
    Спасибо.
  21. Пост Brovin Yaroslav - сообщение в Возможно ли подключиться к MySQL без DLL на Андроиде? был отмечен как ответ   
    Можете использовать контролы украинского компании Devart.
    В этой статье они рассказывают как раз то, что вам нужно: How to Develop iOS Applications in Delphi XE4 Using Devart Data Access Components
     
  22. Пост Brovin Yaroslav - сообщение в Помогите перевести код с Delphi на С++ по использованию TTextLayout был отмечен как ответ   
    Описанная вами проблема в вашем коде:
    FTextLyout = (TTextLayout*)(new TTextLayoutClass(TTextLayoutManager::DefaultTextLayout));  Абсолютно неправильно создаете объект TTextLayout. Нужно так:
    TTextLayoutClass textLayoutClass = TTextLayoutManager::DefaultTextLayout; TTextLayout* FTextLyout = TTextLayoutManager::TextLayoutForClass(textLayoutClass); Но здесь есть два важных момента. Вообще создание экземпляра переменной классового типа (Delphi) возможность языка Delphi, а не С++.
    И в С++ такой поддержки нету. Поэтому подобные создания объектов по делфовым классовым значениям (class of) выносят на сторону Delphi. Что в данном случае и сделано при помощи метода класса TextLayoutForClass. Которые и осуществляет создание объекта по делфовому классу.
     
    TTextLayoutClass - это наследник от TMetaClass<> и по сути внутри себя держит указатель на делфи класс. поэтому обычным оператором new объект вы не создадите.
     
    P.S. 32-битная версия компилятора С++ имеет ошибку, которая исправлена в XE6. 
  23. Пост Brovin Yaroslav - сообщение в Как сделать автоматическое изменение высоты TListBoxItem под содержимое текста? был отмечен как ответ   
    Ответ косвенно был дан в теме Автоматический переход на вторую строку TLabel
     
    Поэтому на базе этого ответа его легко модифицировать для этой задачи. Идея простая в момент загрузки стиля и изменения размеров TListBoxItem, вычислять высоту занимаемого текста и на основании этих данных переопределять высоту итема.
     
    Практика
    1. Для определения размеров текст используем TTextLayout. Лучше создавать объект этого класса один раз. Поскольку в нашем случае он будет использоваться часто.
    procedure TForm1.FormCreate(Sender: TObject); begin // FTextLyout: TTextLayout - поле формы FTextLyout := TTextLayoutManager.DefaultTextLayout.Create; end; procedure TForm1.FormDestroy(Sender: TObject); begin FreeAndNil(FTextLyout); end;  2. Пишем свой обработчик, который мы будем вызывать по достижению двух событий:
    Изменение размера TListBoxItem. В этом случае нужно перевычислить высоту итема. При загрузки нового стиля итема, нам нужно заново вычислить высоту итема. Поскольку стиль может содержать новые настройки отображения текста (шрифт, размер и тд.) Я назвал это событие CalculateItemHeght:
    procedure TForm1.CalculateItemHeight(Sender: TObject); var ListItem: TListBoxItem; begin if Sender is TListBoxItem then begin ListItem := Sender as TListBoxItem; FTextLyout.BeginUpdate; try // Инициализируем текстовый слой для корректного вычисления // размеров отображаемого текста FTextLyout.Text := ListItem.Text; FTextLyout.MaxSize := TPointF.Create(ListItem.Width, 1000); FTextLyout.WordWrap := ListItem.WordWrap; FTextLyout.Font := ListItem.Font; FTextLyout.HorizontalAlign := ListItem.TextAlign; FTextLyout.VerticalAlign := ListItem.VertTextAlign; finally FTextLyout.EndUpdate; end; // Получаем высоту текста при текущих настройках итема ListItem.Height := FTextLyout.Height; end; end; Обратите внимание, что этот код работает для горизонтальной ориентации TListBoxItem и обычного TListBoxItem итема без картинок. Поэтому я для упрощения понимания кода, принимаю за ширину текста ширину самого итема. Но как вы понимаете, текст в итеме имеет еще свои отступы и может располагаться, например, справа от изображения. В этом случае этот в этот код нужно будет добавить определение текущих размеров стилевого объекта текста, отвечающего за вывод текста в TListBoxItem.
     
    Но в вашем примере этого не нужно.
     
    3. Вешаем наш обработчик на два события каждого итема TListBoxItem.OnResize и TListBoxItem.OnApplyStyleLookup.
     
    Результат

     
  24. Пост Brovin Yaroslav - сообщение в Как добавить в свой компонент TImage и дать возможность менять картинку? был отмечен как ответ   
    Добрый день,
     
    Если есть исходники FMX, то посмотрите на реализацию контрола FMX.StdCtrls.TImageControl, не стесняйтесь их изучать. Там как раз аналогичная ситуация, есть встроенный TImage, в который загружается пользовательское изображение.
     
    Общие правила такие:
    Решаем, где будем хранить контейнер для изображения TImage: в стиле или создавать динамически при создании нашего контрола? Любое изображение нужно где-то хранить, вариант с загрузкой по пути не самый удачный на мой взгляд. Так как пути на разных платформах будут разными, да и возникает необходимость разворачивания файлов изображений вместе с пакетом (Deployment Manager - Включение своих файлов в приложение). Единственный плюс при этом - это экономия на памяти и ускорение запуска программы, за счет отложенной загрузки изображения. Это может стать решающей причиной для хранения изображения по пути к файлу со всеми вытекающими. Изображение храним в TBitmap, который создается динамически. Доступ к нему открывается в published секции для работы в DesignTime. В этом случае пользователь сможет загрузить свое изображение в дизайн тайме и при этом оно при сохранении формы автоматически сериализуется в ресурсы формы, а в последующем и восстановится. Осталось настроить загрузку изображения непосредственно в компонент отображения. В нашем случае в TImage. Если TImage создается динамически нашим контролом и не зависит от стиля, то смело грузим картинку из TBitmap в TImage.Bitmap. Если же контейнер загружается из стиля, то грузим картинку в перекрытом методе ApplyStyle, который вызывается, когда стиль загружен для контрола.
  25. Пост Brovin Yaroslav - сообщение в Какое назначение у свойства TFmxObject.Stored? был отмечен как ответ   
    Назначение свойства Stored
    Stored - нужно, чтобы указать нужно ли сохранять созданный объект в ресурсы формы или нет. Например, стилевые объекты не должны сериализоваться и сохраняться в ресурсы формы поскольку стиль загружается динамически в рантайме. И если он сериализуется в дизайн тайме, то в рантайме будет двойная загрузка стиля. Первый раз из ресурсов, второй раз уже динамически механизмом стилизации. Что как вы понимаете не верно. Поэтому у таких объектов, создаваемых в рантайме Stored устанавливается в False.
     
    Это свойство никак не влияет на работу обработки событий мыши. Без stored все должно работать корректно. 
     
    В чем ошибка?
    Однако у вас есть ошибка, которая к этому поведению и привела и связана с неиспользованием свойства Stored.
    Первый раз, когда вы бросаете компонент на форму, он создает в дизайн тайме прямоугольник и привязывает его к вашему контролу. Все бы ничего, но когда вы сохраняете форму, ваш прямоугольник сериализуется в ресурсы формы. Затем идет запуск программы. Вначале отрабатывает конструктор вашего компонента и он, естественно, создает прямоугольник в рантайме. Но затем идет чтение еще одного прямоугольника, который читается и располагается поверх созданного контролом прямоугольника. Но в отличии от первого он уже не имеет заданного обработчика. В итоге в рантайме, созданный прямоугольник располагается внизу. А затем он перекрывается аналогичными прямоугольниками, созданными из ресурсов формы. Вот и весь секрет
×
×
  • Создать...