-
Постов
2 124 -
Зарегистрирован
-
Посещение
-
Победитель дней
390
Сообщения, опубликованные Brovin Yaroslav
-
-
-
-
Добрый вечер,
Тут есть два способа:- Работа с Deployment менеджером. Он довольно подробно описан на Embarcadero Doc Wiki: http://docwiki.embarcadero.com/RADStudio/XE5/en/Deployment_Manager
- Работа через менеджер ресурсов и их получение через ResourceStream. Этот способ описал MyDelphiPw в сообщении выше тут.
1. Deployment Manager
Специальная настройка проекта, которая позволяет указать, какие файлы нужно включить в состав пакета (Андроид) или бандла (iOS). Суть его работы простая, вы указываете какие файлы с вашего компьютера нужно перенести на устройство (в какое место). А далее работаете с ними из приложения так, как при обычной работе с файлами под Windows.На мобильных платформах нужно учесть специфику возможных местоположений файла. Пакет/Бандл (приложение) не допускает изменения внутренних файлов, потому что подписывается сертификатом. Поэтому теоретически при изменении файлов приложения, вы нарушаете целостность подписи. Именно по этому файлы внутри пакета/бандла доступны только на ЧТЕНИЕ.
Однако, мобильные платформы предлагают широкий круг специальных мест для хранения (временные папки, песочницы, документы, карточка памяти и тд) изменяемых файлов (например файл локальной базы данных, или настройки в ini файле и тд).
Описание всех вариантов местоположений с описанием путей есть в записе TPath (RTL): http://docwiki.embarcadero.com/RADStudio/XE5/en/Standard_RTL_Path_Functions_across_the_Supported_Target_Platforms.
Общие действия для использования менеджера развертывания такие:
1. Открываем менеджер развертывания: Системное Меню -> Project -> Deployment.
2. Выбираем в верхнем выпадающем меню платформу и конфигурацию сборки.
3. Нажимаем кнопку добавить файл и выбираем нужный файл.
4. Указываем местоположение файла, куда он должен поместиться после развертывания приложения на устройстве. Тут есть особенность, если файл нужен только на чтение, то пути менять не надо. Если возможна ситуация, когда файл может быт изменен, то файл нужно поместить под iOS в Startup\Documents\ (регистр важен)
Под Андроид в assets\internal (регистр важен) - для внутреннего доступа из пакета приложения или assets - для внешнего доступа
5. Получаем пути к расположению файлов:
Под iOS:TPath.Combine(TPath.GetDocumentsPath, 'filename')
Под Андроид:
TPath.Combine(TPath.GetDocumentsPath, 'filename') { Внутренний доступ} TPath.Combine(TPath.GetSharedDocumentsPath, 'filename') { Внешний доступ }
Полезные ссылки
- Подробное руководство по добавлению файлов для iOS: http://docwiki.embarcadero.com/RADStudio/XE5/en/Creating_an_iOS_App#Loading_and_Deploying_Files
- Подробное руководство по добавлению файлов для Android: http://docwiki.embarcadero.com/RADStudio/XE5/en/Creating_an_Android_App#Loading_and_Deploying_Files
-
Здесь есть два варианта решения:
1. Использовать сервис FMX.Types.IFMXMouseService
Этот сервис позволяет получить координаты последнего положения курсора мыши, нажатия или перемещения пальца по экрану. Однако если пользователь оторван палец от экрана, то сервис вернет последнее положение пальца на экране. Этот метод хорош тем, что позволяет узнать положение в любой момент в любом месте экрана. Метод возвращает абсолютные координаты в СК формы. При использовании этого варианта и при частой необходимости получать координаты, сервис лучше сохранить локально в отдельную переменную, чтобы каждый раз не выполнять запрос на получение сервиса. Так как эта функция требует дополнительных ресурсов.
var MouseService: IFMXMouseService; MousePos: TPointF; begin // MouseService - лучше вынести отдельным полем класса и инициализировать ее например при создании формы. if TPlatformServices.Current.SupportsPlatformService(IFMXMouseService, IInterface(MouseService)) then MousePos := MouseService.GetMousePos end;
2. Использовать глобальный объект Screen: TScreen
В FireMonkey есть глобальный объект, который предоставляет информацию о экране. Он внутри использует несколько сервисов.
В частности, у него есть метод:
Screen.MousePos
Который использует 1 подход и вернет такой же результат. Но в отличии от первого способа, тут не нужно запрашивать сервис, это сделано в TScreen.
3. Использовать стандартные события OnMouseDown, OnMouseMove, OnMouseUp
Собственно способ заключается в определении текущего положения пальца через событие OnMouseMove. Однако, этот способ подходит только для контролов, которые могут перехватывать события мыши (HitTest = True). Идея
-
Вся отрисовка выполняется в главном потоке приложения. Поэтому, если вы пытаетесь выполнить скачивание файла в основном потоке, то вся отрисовка приостановится до момента окончания вашей операции. Поэтому правило хорошего тона - это вынесение долгих операций (загрузка, ответ авторизации и тд) в отдельный поток.
Примерный код приведен ниже:
1. Создаем отдельный поток, в котором вы будите скачивать файл (я поставил для эмуляции скачивания просто паузу на 5 секунд):type TMyTask = class (TThread) protected FOnTaskStarted: TThreadMethod; FOnTaskFinished: TThreadMethod; procedure DoStarted; procedure DoFinished; procedure Execute; override; public property OnTaskStarted: TThreadMethod read FOnTaskStarted write FOnTaskStarted; property OnTaskFinished: TThreadMethod read FOnTaskFinished write FOnTaskFinished; end;
Реализация:
{ TMyTask } procedure TMyTask.DoFinished; begin if Assigned(OnTaskFinished) then OnTaskFinished; end; procedure TMyTask.DoStarted; begin if Assigned(OnTaskStarted) then OnTaskStarted; end; procedure TMyTask.Execute; begin Synchronize(DoStarted); try Sleep(5000); // Эмуляция выполнения 5 Секундной задачи finally Synchronize(DoFinished); end; end;
Само использование такого потока будет следующим (в моем примере после выполнения операции, появится сообщение):
TForm3 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private FMyTask: TMyTask; public procedure DoTaskStarted; // Callback, вызываемый в начале старта операции procedure DoTaskFinished; // Callback, вызываемый в конце выполнения операции. Аналог OnTerminate procedure StartMyTask; // Запуск задачи end;
procedure TForm3.Button1Click(Sender: TObject); begin StartMyTask; end; procedure TForm3.DoTaskStarted; begin end; procedure TForm3.DoTaskFinished; begin ShowMessage('Выполнение задачи окончено'); end; procedure TForm3.StartMyTask; begin if FMyTask <> nil then begin FMyTasl.OnTaskStarted := nil; FMyTasl.OnTaskFinished := nil; FMyTask.Free; end; FMyTask := TMyTask.Create(True); FMyTask.OnTaskStarted := DoTaskStarted; FMyTask.OnTaskFinished := DoTaskFinished; FMyTask.Start; end;
При таком подходе главный поток не будет блокироваться и будет корректно отрисовываться и работать.
-
FireMonkey позволяет гибко управлять видимостью статус бара под iOS. Причем управление видимостью происходит на уровне каждой формы по отдельности.
Видимость системного статус бара в рамках одной формы управляется через свойство формы TForm.BorderStyle.
- Значение TBorderStyle.bsNone скрывает системный тулбар для формы растягивает форму на весь экран.
- Все остальные значения отличные от TBorderStyle.bsNone отображают статус бар
-
В текущей версии среды Rad Studio XE5, открыть страницу можно только предварительно создав временный файл с html-текстом страницы. А затем открыть ее в браузере, передав, ссылку на временный файл. В будущем, не исключено, что появится более удобный способ загрузки своей страницы напрямую, без использования временного файла.
Решение может выглядеть так (Но нужно проверить, у меня нету сейчас под рукой устройства):- Создаем TStringList и заполняем код html-страницы (Возможно нужно будет указать кодировку)
- Получаем директорию, где хранятся в текущей системе временные файлы. TPath.GetTempPath (Все варианты путей есть здесь TPath)
- Сохраняем html-страницу в временный файл
- Открываем страницу, используя формат URL для открытия файлов.
P.S. Будет здорово, если вы проверите работоспособность кода и отпишитесь здесь о результатах.
-
Решение у этой задачи простое - это вложенные Таб контролы. Для этого нужно:
- Разместить на форме TTabControl, у которого вкладки будут отображаться снизу (TabPosition = tpBotttom);
- Создать в табконтроле вкладки;
- Разместить еще один TTabControl на вкладке и задать ему (TabPosition = tpNone).
-
Label1.StyledSettings := Label1.StyledSettings - [TStyledSetting.Size];
В FireMonkey все, что отвечает за визуальную часть (отображение контрола) обычно выносится в стиль. Однако, не всегда удобно создавать новый стиль, только, когда нужно, например, поменять размер шрифта в TLabel. Поэтому, чтобы позволить пользователям удобно менять такие настройки, как шрифт. Шрифт выделен в отдельное свойство TLabel.Font. При выделении шрифта отдельным свойством, нужно понимать, что при таком подходе контрол "не знает", откуда ему брать шрифт: то ли из свойства, то ли из стиля.
Поэтому, чтобы контрол знал, откуда ему брать шрифт для отображения: из стиля или из свойства Font, введено свойство TLabel.StyledSetting. Которое говорит контролу, какие характеристики шрифта нужно брать из стиля, а какие можно взять из свойства TLabel.Font. По умолчанию, StyledSettings настроены так, что все берется из стиля. В вашем случае, нужно сбросить галку напротив значения ssSize и ssFont.
Подробная информация есть на Embarcadero Doc Wiki: http://docwiki.embarcadero.com/RADStudio/XE5/en/Setting_Text_Parameters_in_FireMonkey
-
Введение
Появление экранов повышенной плотность физических точек, привело с одной стороны к проблеме адаптации графического интерфейса под разные разрешения экранов при их одинаковых физических размерах, с другой к увеличению четкости и качества картинки.
Например, если раньше на iPhone 3 при размере экрана 3,5 дюйма позволял отобразить 320х480 точек, то на устройстве iPhone 4 при таком же физическом размере экрана, экран мог уже отображать 640х960 точек. Это хорошо видно на увеличенном изображении обычного экрана и ретина экрана на рисунке ниже (слева - не ретина, справа - ретина (2х)). Справа количество физических точек ровно в четыре раза больше, чем слева:Для разработчика это могло означать, что интерфейс привязанный к разрешению 320х480 на Retina экране будет занимать только четверть экрана. Естественно, что использование разрешения экрана в физических координатах не удобно с этой точки зрения. Именно по этому появились логические координаты, которые гарантируют, что тот же пользовательский интерфейс для iPhone 3, будет иметь такие же размеры (физические) и на экране с ретиной.
FireMonkey работает в логических координатах. Это означает, что на iPhone 3 - 4 мы работаем с логическим разрешением 320x480 точек. Однако, при отображении интерфейса на iPhone 4 c (с двойной плотностью пикселей по сравнению с iPhone 3), интерфейс автоматически масштабируется на физическое разрешение 640х960 с коэффициентом масштабирования равным 2.
Практика
Теперь посмотрим, как получить всю эту информацию. Вся информация об экране (логический размер и коэффициент масштабирования) находится в сервисе IFMXScreenService.
Чтобы получить физическое разрешение экрана, нужно логический размер умножить на коэффициент масштабирования.
Код ниже показывает, как получить доступ к этому сервису и извлечь требуемые параметры:var ScreenService: IFMXScreenService; LogicScreenSize: TPoint; ScreenScale: Single; begin // Запрашиваем сервис экрана, для получения информации о размере и текущем коэффициенте масштабирования if TPlatformServices.Current.SupportsPlatformService(IFMXScreenService, IInterface(ScreenService)) then begin LogicScreenSize := ScreenService.GetScreenSize.Round; ScreenScale := ScreenService.GetScreenScale; LabelLogicScreenSize.Text := Format('Логический размер: %d, %d', [LogicScreenSize.X, LogicScreenSize.Y]); LabelPhysicScreenSize.Text := Format('Физический размер: %f, %f', [LogicScreenSize.X * ScreenScale, LogicScreenSize.Y * ScreenScale]); LabelScreenScale.Text := Format('Коэффициент масштабирования: %f',[ScreenService.GetScreenScale]); end; end;
Результат кода приведен на снимке экранов ниже для iPad устройств с ретиной экраном и без:
-
На эту тему есть хорошая статья доступная по ссылке: Firemonkey на практике #2. Освещение и материал поверхности 3D объектов
-
Здесь есть несколько вариантов:
- Создать самостоятельно из компонентов FireMonkey: TLayout, TButton. Сделать специальные стили для кнопок и затемнения и в IOS написать код по выдвижению панели, как описано в этой теме: "Как создать выдвигаемую панель?". Такой вариант будет кроссплатформенным и вы сможете легко настроить его на ваш вкус.
- Использовать нативный компонент в iOSAPI UIActionSheet. В этом варианте решение будет только для iOS, но зато вам не надо будет думать о специфичной стилизации. Стиль будет браться системный.
- Использовать готовый OpenSource компонент TfgActionSheet, который использует под каждой мобильной платформой нативные контролы. В том числе под iOS используется тот же UIActionSheet. Под андроид это сделано в виде диалога с кнопками действий. компонент входит в состав этого пакета для Delphi fgx_0.3.0.11.zip. Однако, нужно правильно настроить правила сборки этого пакета.
-
Как и в любой задаче, здесь есть несколько вариантов решения. Каждый вариант обладает своими достоинствами и характеризуется степенью сложности реализации. На вскидку, мне кажется, что следующий вариант будет лучшем в вашем случае:
Отдельный компонент-контрол TSnowFall
Назовем его условно TSnowfall (снегопад). Он будет рисовать на себе падающие снежинки. Мы располагаем его в корне формы и растягиваем на весь экран Align = alContent, так же всегда располагаем его поверх всех остальных контролов (BringToFront) и запретим ему перехватывать события мыши (HitTest = False), чтобы он не нарушал логику работы всех остальных контролов. Затем в перекрытом методе TControl.Paint выполняем отрисовку снежинок с текущими позициями. А в созданном вручную таймере по каждому тику меняем текущее положение всех снежинок и вызываем метод перерисовки TControl.Repaint.
На мой взгляд этот вариант хорош:
- Полное отделение логики от кода формы. То есть код формы будет проще за счет убирания всего кода работы с отрисовкой снежинок в отдельный юнит.
- Легкое расположение занавеса снежинок в любом месте. С возможностью привязки к любому контролу и без.
- Повторное использование в любом другом месте.
Постусловие
Каждая форма FireMonkey имеет одну канву. Поэтому все контролы по сути рисуются на ней, в отличии от VCL, где каждый контрол с оконным хендлом имеет свой графический контекст -> канву.
Когда форма получает запрос на отрисовку, она по шаблону цепочка ответственности делегирует всем контролам по дереву запрос на отрисовку.
В каждом контроле происходит подготовка общей канвы под отрисовку нужного контрола, который в текущий момент отрисовывается. То есть задается матрица трансформации, чтобы контрол работал в своей локальной системе координат, а не в абсолютной СК формы. И тд. Поэтому теоретически вы можете рисовать поверх любых контролов в TForm.OnPaint, но это правильно. Лучше использовать мой предложенный подход, описанный выше.
-
Самый простой вариант использования эффекта прокручивания основывается на использовании компонента TTabControl, который реализует переключение табов (вкладок) с анимацией. Для этого достаточно:
- Поместить TTabControl на форму и растянуть его на всю область TTabControl.Align = alClient.
- Создать вкладки. Одну вкладку на один логический экран (слайд, представление и тд). На каждую вкладку помещаете любой контент. В вашем случае TListBox.
- Вызвать в нужный момент метод переключения вкладок с анимацией:
TTabControl.SetActiveTabWithTransition(const ATab: TTabItem; ATransition: TTabTransition; const ADirection: TTabTransitionDirection = TTabTransitionDirection.tdNormal)
Где,
- ATab: TTabItem - Вкладка, которую нужно отобразить
- ATransition: TTabTransition - Отобразить вкладку мгновенно или с эффектом сдвига (В вашем случае нужно второе TTabTransition.ttSlide)
- ADirection: TTabTransitionDirection - направление эффекта сдвига: Слева на право (TTabTransitionDirection.tdNormal) или с права налево (TTabTransitionDirection.tdReversed).
Второй способ
Аналогично создаем Таб контрол с вкладками, но для переключения вкладок используем стандартное действие TChangeTabAction, которое выполняет те же действия, что и SetActiveTabWithTransition. Действия доступны в редакторе TActionList "New Standart Action..."
-
Официальный сайт: http://www.digifort.com/home
Обзорная статья: http://habrahabr.ru/company/delphi/blog/205656/Видео обзор: http://www.youtube.com/watch?v=4lQGA8-sO9w
Наш основной продукт решает задачи в области IP-TV-наблюдения на основе TCP/IP передачи закодированных изображений с аналоговых или IP-камер. Предусмотрена запись для последующего анализа. Технологии Digifort могут быть использованы в качестве основы для реализации анализа видео на предмет соответствия заданным шаблонам для идентификации проблемных ситуаций. Например, можно записывать изображения номеров машин, помещать их в базу данных, распознавать случаи угона. Естественно, можно представить себе и ряд других сценариев использования нашей системы. У нас есть масса продуктов, которые могут быть агрегированы в единое решение для создания замкнутых решений проблем безопасности вплоть до корпоративных потребностей.
-
Project -> Options... -> Application
В Target поставить необходимую платформу и указать пути до изображений.
Для Андроид там задаются только иконки приложения. Чтобы задать SplashScreen для Андроида нужно действовать другими способами. Их несколько, но мне нужно их все проверить:
- Простой - Создание легковесной формы с картинкой (Splash Form) и отображение ее до создания основных форм. Затем после загрузки всех требуемых форм и ресурсов, скрыть Splash Sсreen.
- Сложный - Создать отдельное активити с загрузочной картинкой и после загрузки открыть активити приложения.
-
- Чтобы сделать прозрачным статус бар, нужно отредактировать стиль панели, и либо задать альфа канал для заливки прямоугольника панели (если стиль панели векторный), либо изменить прозрачность используемой png.
- Цвет можно поменять только поменял исходник, либо сделав свой стиль.
- Объединить системный статус бар и тулбар включительно до версии RAD Studio XE5 не удастся. Только поддержка старого варианта: отдельно системный статус бар.
-
-
Вас интересует ситуация только с MediaPlayer или вопрос касается любых контролов?
-
Не понимаю. Что надо написать для того чтобы например на OS X переместить курсор в позицию 100 100?
Для OSX нужно воспользоваться следующим куском кода, не забыв подключить Macapi.CoreGraphics:
uses Macapi.CoreGraphics; procedure TForm5.ButtonSetMousePosClick(Sender: TObject); begin CGWarpMouseCursorPosition(CGPointMake(100, 100)); end;
-
Да, так можно сделать любой вариант выдвижной панели, в том числе выдвижение сбоку экрана на мобильных устройствах.
-
Спасибо за предоставленные ссылки пользователю MyDelphiPw. Текст получен путем разбития его темы на две:
- Нативные компоненты - D.P.F Delphi iOS Native Components
- Нативные компоненты - D.P.F Delphi Android Native Components
Текст ниже, написан пользователем MyDelphiPw.
----------------------------------------------------------------------
Хочу поделиться с пользователями данного ресурса ссылками на нативные компоненты для Delphi под iOS и Android.Автор: Babak Yaghoobi
Тип лицензии: Open Source
Ссылка на проект D.P.F Delphi iOS Native Components (OpenSource): http://sourceforge.net/projects/dpfdelphiios/
Скачать: ZIP, SVN
Description
Develop Native iOS applications with Delphi XE4 / XE5
Develop iPhone & iPad & iPod Touch apps with fast native performance and native styles.
Why choose D.P.F iOS Native components for your mobile app development needs?
* Use native iOS controls and services
* Fast native performance
* Mixed Some Components with FMX controls
* Can be quick updated with latest iOS controls & features
* Improved all components & classes for iOS6 & iOS7
Some Wrapped Frameworks:
* AddressBookUI.framework
* AddressBook.framework
* iAd.framework
* EventKit.framework
* GameKit.framework
* MapKit.framework
* MessageUI.framework
* MobileCoreServices.framework
* QuickLook.framework
* SystemConfiguration.framework
* Social.framework
* StoreKit.framework
* WebKit.framework
Приложение, написанное на этом фреймворке -
P.S. Ярослав, не хватает спойлера в редакторе статей, что бы прятать большое количество скринов, или длинный текст, который может быть не всем нужен.
Ок, постараюсь добавить.
-
Не за что, обращайтесь.
Как сделать перемещение контрола мышкой/пальцем?
в Перемещение контролов
Опубликовано
Добрый вечер,
Перемещение контрола можно сделать двумя способами:
1. Реализация с использованием событий мыши
Эти события реализованы для всех платформ. В том числе они эмулируются на мобильных платформ, где понятия мыши, как такового нету. Это означает, что их можно использовать для реализации перетаскивания контрола. Это можно сделать, например, следующим образом:
а) Создаем форму и кидаем на нее картинку. Я назвал ее DraggableImage.
б) Заводим два поля.
в) В конструкторе формы для перетаскиваемого контрола ОБЯЗАТЕЛЬНО задаем AutoCapture = True. Это позволит контролу генерировать события перемещения мыши, даже если курсор мыши ушел за локальные границы контрола.
г) В момент нажатия на картинку сохраняем локальную позицию мыши и задаем флаг FPressed = True
д) В момент отпускания кнопки мыши или убирания пальца с экрана сбрасываем флаг FPressed:
е) И собственно меняем позицию картинки, когда мы ведем мышкой по картинке:
Этот кусок стоит прокомментировать, чтобы корректно выполнить перетаскивание контролу обязательно нужно вычислять смещение в абсолютных координатах формы. Причина в том, что если контрол повернут или входит один в другой, то нужно учитывать смещения всей цепочки родительских контролов до формы. Поэтому мы вначале вычисляем смещение в локальных координатах, затем вычисляем его в абсолютных координатах формы. А затем обратно переводим в локальные координаты родительского контрола. После чего изменяем позицию контрола на вычисленное смещение.
Такой подход используется, в частности, в контроле TSelection, который так же можно перемещать мышкой или пальцем.
P.S. Чтобы лучше понять это, нарисуйте на листке бумаги положения контрола и попробуйте вручную выполнить этот алгоритм с преобразованием координат.
Собственно говоря, такой подход отлично работает везде и не требует использования системы жестов.
2. Реализация с использованием жестов
Этот способ будет работать только на мобильных платформах, поскольку нужный жест Pan (если я правильно помню) не поддерживается под Windows. Поэтому в целом, первый вариант является универсальным и лучшим решением.