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

Brovin Yaroslav

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

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

  • Посещение

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

    390

Весь контент Brovin Yaroslav

  1. Добрый день, Да, выглядит достойно. Один только момент относительно использования компонента TMultiView: Он создает дополнительный контрол (TShadowedOverlayLayout), который перехватывает события касаний для определения момента выдвижения с края формы. Поэтому для этого контрола важно всегда находится поверх всех контролов формы. В тот момент, когда вы подключаете фрейм, фрейм по сути становится BringToFront и перекрывает TShadowedOverlayLayout и блокирует выдвижение TMultiView. Чтобы этого избежать есть два варианта: Первый вариант, дополнительно обновить выравнивание TMultiView в момент прикрепления фрейма: procedure TfmMain.TabItemNext(ANextFrame: TFrameClass); begin FFrame.DisposeOf; FFrame := nil; FFrame := ANextFrame.Create(Self); FFrame.Parent := Self; FFrame.Align := TAlignLayout.Client; // Если TMultiVIew использует Drawer режим, то перемещает контрол перехвата на верх. if mvMenu.Presenter is TMultiViewDrawerBasePresentation then TMultiViewDrawerBasePresentation(mvMenu.Presenter).DetailOverlay.BringToFront; mvMenu.HideMaster; end; Второй вариант, является в более хитрой комбинации TMultiView.TargetControl и фреймов и не требует дополнительно обращаться к drawer представлению TMultiView: Размещаем в корне формы TPanel или TLayout. Фрейм размещаем в TPanel или TLayout (см. 1 пункт). procedure TfmMain.TabItemNext(ANextFrame: TFrameClass); begin FFrame.DisposeOf; FFrame := nil; FFrame := ANextFrame.Create(Self); FFrame.Parent := Panel1; // <-- а при втором подходе размещаем фрейм в дополнительном контейнере FFrame.Align := TAlignLayout.Client; mvMenu.HideMaster; end; TMutliView при загрузке представления (смены режима отображения) размещает TShadowedOverlayLayout в корне формы и отображает его по верх всех контролов формы. При использовании панели или слоя, TShadowedOverlayLayout будет всегда расположен поверх.
  2. Добрый день, Рекомендую к прочтению: Почему для некоторых контролов нельзя поменять высоту или ширину? Если же, все-таки очень хочется задать 24 шрифт для TEdit, тогда следуем руководству: [Android] Не получается увеличить высоту TProgressBar
  3. Добрый день, Вы можете поменять частоту срабатывания анимации. TAnimation.AniFrameRate отвечает за указания своей частоты срабатывания анимации. По умолчанию она равна 60 кадров в секунду. Значащие значения в диапазоне [5, 100]. Значения больше или меньше этого диапазона приводятся к нему же. Эффекты дорогостоящие операции. Поэтому их использование должно быть сведено к необходимому минимуму, особенно в анимации. В FireMonkey для ускорения эффектов, эффекты кешируются в контроле, к которому применяются. Однако, кэш не работает для анимации эффектов.
  4. Beta hotfix for FireMonkey apps on Android 5.0 (Lollipop) Available to registered users of RAD Studio XE7, Delphi XE7 and C++Builder XE7 (except non-mobile editions) and Embarcadero All-Access XE Скачать: http://cc.embarcadero.com/item/30110
  5. Я бы воспользовался новым механизмом, появившимся в XE7 Save State. Унифицировано, гибко. Описание работы и примеры, в документации: FireMonkey Save State
  6. Хорошо, что задали этот вопрос. Потому, что я вспомнил о более лаконичном и удобном решении. Чем тот, что я вам предложил. В XE7 был переведен на MVC модель. В итоге, TEdit позволяет не создавая наследников менять и дополнять работу TEdit. Идея простая, у TEdit есть несколько представлений, которые полностью осуществляют работу TEdit. Чтобы исправить это отклонение, нужно создать новое представление и заменить текущей TStyledEdit на новое, исправленное: unit FMX.Edit.MyStyle; interface uses FMX.Edit.Style, FMX.Controls.Presentation, System.UITypes, System.Classes; type // Новое представление - расширение текущего TMyStyledEdit = class(TStyledEdit) protected procedure MouseClick(Button: TMouseButton; Shift: TShiftState; X, Y: Single); override; end; // Промежуточный класс TMyStyledEditProxy = class(TPresentationProxy) protected function CreateReceiver: TObject; override; end; implementation uses System.SysUtils, FMX.Presentation.Factory, FMX.Types; { TMyStyledEditProxy } function TMyStyledEditProxy.CreateReceiver: TObject; begin Result := TMyStyledEdit.Create(nil); end; { TMyStyledEdit } procedure TMyStyledEdit.MouseClick(Button: TMouseButton; Shift: TShiftState; X, Y: Single); var Control: IControl; begin inherited; if Supports(PresentedControl, IControl, Control) then Control.MouseClick(Button, Shift, X, Y); end; initialization // Для всех TEdit удаляем базовое представление TPresentationProxyFactory.Current.Unregister('Edit-Style'); // Для всех TEdit регистрируем наше представление TPresentationProxyFactory.Current.Register('Edit-Style', TMyStyledEditProxy); finalization // Восстанавливаем старое представление Edit TPresentationProxyFactory.Current.Unregister('Edit-Style'); TPresentationProxyFactory.Current.Register('Edit-Style', TStyledEditProxy); end. Где немного упоминается о новом подходе: Нативные элементы управления Куда пропали методы DoChangeTracking и Change? Для исправления, достаточно добавить этот файл в проект. Этого будет достаточно. Проект: NewEditPresentation.zip
  7. У вас банальная ошибка. Вы объявили переменную, как поле формы. Но при этом локальную переменную MyHTTP1 не удалили!!!
  8. У меня работает, а у вас нет? Ищите, где допустили ошибку. Попробуйте загрузить другие картинки. Почистите ваш код от мусора. Сделать за вас я это не смогу.
  9. Да, кстати, в TThread есть специальный метод CreateAnonymousThread, который позволяет выполнить ваш код в другом потоке без создания отдельного класса потока: class function TThread.CreateAnonymousThread(const ThreadProc: TProc): TThread; static; Внутрь передается указатель на процедуру без параметров.
  10. Да, при помощи потоков Переменную MyHTTP1 объявите в классе формы: TForm8 = class(TForm) IdHTTP1: TIdHTTP; Image1: TImage; Button1: TButton; procedure Button1Click(Sender: TObject); private MyHTTP1: ThreadHTTP1; public { Public declarations } end;
  11. Все очень просто, ваш тред убивается быстрее, чем успевает запуститься. Потому что на всех мобильных платформах работает ARC, вы объявили переменную треда в локальном скопе. В итоге, при выходе из процедуры, счетчик ссылок вышей переменной сбрасывается на 0 и ваш тред распускается. Ваш код: procedure TForm3.Button1Click(Sender: TObject); var MyHTTP1:ThreadHTTP1; begin MyHTTP1 := ThreadHTTP1.Create(False); end; Будет дополнен после компиляции дополнительными служебными командами: procedure TForm8.Button1Click(Sender: TObject); begin MyHTTP1 := ThreadHTTP1.Create(True); { MyHTTP1.__ObjAddRef; } <-- В момент присваивания потока в MyHTTP1. RefCount = 1. MyHTTP1.Start; { MyHTTP1.__ObjRelease; } <-- В момент выхода из метода. RefCount = 0 -> Вызов Деструктора end; Частично ответ есть тут (Первые параграфы ответа): Как правильно удалять контролы в RunTime? Соответственно, нужно обеспечить время жизни переменной такой же, как и у потока. Для этого можно просто оформить переменную, как поле класса.
  12. А есть ли у вас ссылка на такой сайт с истекшим сертификатом?
  13. Чтобы TBluetooth сменил режим на Discoverable, нужно вызвать метод: TBluetooth.StartDiscoverable(Timeout: Integer);
  14. Классический TBluetooth не поддерживает эту информацию. Но TBluetoothLE позволяет узнать это. Для этого нужно воспользоваться событием: TBluetoothLE.OnReadRSSI(const Sender: TObject; ARssiValue: Integer; AGattStatus: TBluetoothGattStatus)
  15. Для Delphi: var EditControl: TControl; SenderEdit: TEdit; begin if Sender is TStyledEdit then begin EditControl := TStyledEdit(Sender).PresentedControl; SenderEdit := EditControl as TEdit; end; end; Для C++ Builder #include <FMX.Edit.Style.hpp> TStyledEdit* styledEdit = dynamic_cast<TStyledEdit*>(Sender); if (styledEdit) { TEdit* edit = dynamic_cast<TEdit*>(styledEdit->PresentedControl); } P.S. Но это только нужно для устранения этой проблемы. В исправленной версии это не понадобиться.
  16. Часть исходного TBitmap вырезается при помощи отрисовки этой части в другой TBitmap. Допустим есть такой проект: Тогда алгоритм по вырезанию будет следующий: Определяем регион вырезаемой области: var BitmapSource: TBitmap; BitmapDest: TBitmap; DestWidth: Integer; DestHeight: Integer; BitmapSourceRect: TRectF; BitmapDestRect: TRectF; begin BitmapSource := ImageSrc.Bitmap; BitmapSourceRect := TRectF.Create(TPointF.Create(nbX.Value, nbY.Value), nbWidth.Value, nbHeight.Value); Создаем TBitmap для вырезанной части: DestWidth := Max(0, Round(nbWidth.Value)); DestHeight := Max(0, Round(nbHeight.Value)); BitmapDest := TBitmap.Create(DestWidth, DestHeight); BitmapDestRect := TRectF.Create(0, 0, BitmapDest.Width, BitmapDest.Height); Выполняем отрисовку области исходного битмапа в конечный: if BitmapDest.Canvas.BeginScene then try BitmapDest.Canvas.DrawBitmap(BitmapSource, BitmapSourceRect, BitmapDestRect, 1); finally BitmapDest.Canvas.EndScene; end; Выводим полученное изображение на форму: ImageDest.Bitmap.Assign(BitmapDest); Результат:
  17. Размер TEdit больше, так как вычисление размеров текста нужно производить в момент, когда стиль загружен. А при создании в рантайме, контрол загрузит свой стиль при первой отрисовке. Либо же надо перед вычислением размера текста форсировать загрузку стиля вызовом метода: Edit.ApplyStyle;
  18. Для каждого, где требуется OnClick. Чтобы облегчить работу, можно вынести мой код в отдельную процедуру типа SetEditOnClick(AEdit: TEdit; AOnClick: TNotifyEvent); и ее вызывать для требуемых эдитов.
  19. TScrollBox автоматически высчитывает размер скролируемого контента. Поэтому, когда вы помещаете в него контрол и перемещаете его за видимые границы контрола (ViewPort), то TScrollBox пересчитывает размеры контента и добавляет полосы прокрутки. Отсюда следует важный факт, что размер контента TScrollBox зависит от внутернний контролов. Вы пытаетесь добавить внутрь контента Layout, выравненный по всей области скроллбокса. Что вы вы этом случае ожидаете получить на выходе? Как я думаю, вы догадываетесь, что это выравнивание зависит от размер родительского контрола. А сам скролл бокс (предок), использует ваш Layout для определение размера контента. Так что в вашей ситуации TScrollBox для контента возьмет размер самого скролл бокса. Чтобы вам добавить прокрутку нужно: Взять за основу TVertScrollBox Поместить внутрь TLayout (если хотите, можно без него напрямую складывать контролы). Выравнять его по верхнему краю. В этом случае вы сможете руками задать требуемую высоту, при получении новых данных Когда вы будите знать размер вашего изображения, пересчитать высоту и обновить ее для вашего Layout.
  20. d7d1cd, Вопросы касательно обновлений увы не в моей компетенции. На счет "преднамеренных ошибок" могу вас успокоить, это не так.
  21. Да, конечно, код для С++ Builder (При ControlType = Styled): void __fastcall TForm2::FormCreate(TObject *Sender) { TStyledControl* styledPresentation; if (Edit1->HasPresentationProxy()) { styledPresentation = dynamic_cast<TStyledControl*>(Edit1->PresentationProxy->Receiver); styledPresentation->OnClick = Edit1Click; // <-- программно задать свой обработчик } }
×
×
  • Создать...