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

Alisson R Oliveira

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

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

  • Посещение

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

    2

Активность репутации

  1. Like
    Alisson R Oliveira отреагировална DirtyBorov в MaskEdit   
    Случилось так, что потребовался мне ввод номера телефона. Компонента, аналога TMaskEdit в FMX нет, так что пришлось "изобретать на коленке". Компонент писать было лень, потому просто покажу как я решил это в конкретном диалоге с использованием TEdit. Может кому то пригодится. Из кода я убрал все лишнее, оставил только то что относится к делу.
    uses .... System.MaskUtils, System.Character; type TFormRegistry = class(TForm) edtPhone: TEdit; procedure edtPhoneValidating(Sender: TObject; var Text: string); procedure edtPhoneKeyDown(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState); procedure FormCreate(Sender: TObject); procedure edtPhoneEnter(Sender: TObject); procedure edtPhoneTyping(Sender: TObject); private const Mask = '+7(000)000-00-00;0;*'; /// '+0(000)000-00-00;0;*' - для других стран, например для Украины +3(999).... private PhoneNumber: string; function GetCaretPos: Integer; function GetMaxLength: integer; public end; procedure TFormRegistry.FormCreate(Sender: TObject); begin edtPhone.Text := FormatMaskText(Mask, PhoneNumber); end; function TFormRegistry.GetCaretPos: Integer; var i: integer; begin Result := 0; for i := 0 to Mask.Length-1 do begin if not (MaskGetCharType(Mask, i) in [mcDirective, mcMask]) then Result := Result + 1; if (Result + PhoneNumber.Length) = i then Break; end; Result := Result + PhoneNumber.Length - 1; end; function TFormRegistry.GetMaxLength: integer; var i: integer; begin Result := 0; for i := 0 to Mask.Length-1 do if (MaskGetCharType(Mask, i) in [mcMask]) then Result := Result + 1; end; procedure TFormRegistry.edtPhoneKeyDown(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState); begin if (Key = 8) and (PhoneNumber.Length > 0) then PhoneNumber := Copy(PhoneNumber, 1, PhoneNumber.Length-1) else if (PhoneNumber.Length < GetMaxLength) and (Key = 0) and IsDigit(KeyChar) then PhoneNumber := PhoneNumber + KeyChar else KeyChar := #0; end; procedure TFormRegistry.edtPhoneEnter(Sender: TObject); begin edtPhone.CaretPosition := GetCaretPos; end; procedure TFormRegistry.edtPhoneTyping(Sender: TObject); begin edtPhone.CaretPosition := GetCaretPos; end; procedure TFormRegistry.edtPhoneValidating(Sender: TObject; var Text: string); begin Text := FormatMaskText(Mask, PhoneNumber); end; end.
  2. Like
    Alisson R Oliveira отреагировална Равиль Зарипов (ZuBy) в Случайное генерирование цвета   
    вот так делается
    self.Fill.Color:= TAlphaColorF.Create(255/Random(255), 255/Random(255), 255/Random(255), 255/Random(255)).toAlphaColor;
  3. Like
    Alisson R Oliveira отреагировална walexw в обнулить буфер клавиатуры при переходе по TEdit   
    Способ решить эту проблему я ищу почти год, и хоть на форуме несколько раз упоминались похожие темы, решил создать еще одну, т.к. нет никакого решения (все просмотрел).
    На форме 2 или больше TEdit, переход с первого на второй по Enter (Next).
    Все что набрано в первом TEdit, при нажатии любой буквы второго TEdit переносится во второй плюс эта буква (см. скриншот)
    Все это происходит при включенном на телефоне "подсказчике" слов, но он удобен и огромное количество людей им пользуются.
    Приложений у меня было несколько. И на C++ и на Delphi. Использовал RAD XE 10
    Четыре планшета и три смартфона с Андроидами 4, 5, 6 для тестов. Клавиатуры и родные и Гугл.
    Все они как близнецы повторяют этот трюк и как избавится от него, никак не могу найти решение.
    Единственное, что помогает - отключить подсказки в самом телефоне, но это на своем.
    А те кто скачивают программу из интернета, им как быть?
    Благодарен за любые советы (подсказки).
    Сам я ищу возможность обнулить буфер клавиатуры при выходе с одного Эдита и входе в следующий.

  4. Like
    Alisson R Oliveira отреагировална Равиль Зарипов (ZuBy) в Как запретить вставку в TEdit из буфера обмена на android?   
    При открытии/ворачивании в приложение очисти буфер
  5. Like
    Alisson R Oliveira отреагировална Antonyan в Обработчики событий OnTap, OnGesture для элемента стиля   
    Доброго времени суток !
    Вопрос #1
    Как назначить обработчик событий OnTap, OnGesture элементу стиля ? Либо, как еще отловить событие нажатие на элемент стиля, не путая скроллинг и tap?
    Подозреваю, что подобный подход не приемлем :
    ListBoxItem.StylesData['Rectangle.OnTap'] := TValue.From<TNotifyEvent>(..Myprocedure_OnTap...)
    ListBoxItem.StylesData['Rectangle.OnGesture'] := TValue.From<TNotifyEvent>(..Myprocedure_OnGesture...)
    Потому как, TNotifyEvent = procedure(Sender:TObject) of object;
    Вопрос #2.
    Насколько известно, android не различает скроллинг и tap. А как с этим в IOS ?
    Заранее благодарю
     
     
     
  6. Like
    Alisson R Oliveira отреагировална Равиль Зарипов (ZuBy) в Проблема при активации memo или edit программа зависает и закрывается.   
    проект приложите без бинарников
     
    update:
    проблем не выявлено
    попробуйте использовать
    SetFocused(Edit1); Или как-то так
    ActiveControl := Edit1;
  7. Like
    Alisson R Oliveira отреагировална Равиль Зарипов (ZuBy) в Использовать edit в popup форме   
    использовать TMultiView с режимом Custom + FMX.MultiView.CustomPresentation.pas
    смотреть демо пример
     
    кинуть на этот MultiView edit и кнопку, готово
  8. Like
    Alisson R Oliveira отреагировална FREEFAR в Концепция интерфейса приложения для Андроида   
    Например так
    uses FMX.Ani
    Frame.Position.X := clientWidth;
        TAnimator.AnimateFloat(Frame, 'Position.X', 0, 0.2);
    ну понятно что предварительно этот фрей привести к росту/весу основных окон или вписанных областей
  9. Like
    Alisson R Oliveira отреагировална Равиль Зарипов (ZuBy) в TMapsEngine   
    Благодарю, все руки не доходили выложить исправленную версию
  10. Like
    Alisson R Oliveira отреагировална Равиль Зарипов (ZuBy) в TMapsEngine   
    а что именно не понятно?
    1) создаём
    mEngine := TMapsEngine.Create; 2) указываем что будем использовать
    mEngine.SetOptionsYandex(''); mEngine.SetOptionsGoogle(GoogleAPI); mEngine.SetOptionsHere(HereAPI, HereAPP); 3) получаем данные по координатам
    mEngine.Geocoding(myCoordLoc, myGeoLoc); 4) получаем координаты по адресу
    mEngine.GeocodingReverse(myGeoLoc, myCoordLoc); 5) отрисовать маршрут
    mEngine.SetOptionsGoogleDistance(GoogleDistance); // тут !!distance!! api_key google mEngine.GoogleDistance(myCoordLoc, myCoordTap, myRoutePoints, myRouteInfo); // данные о маршруте Примера нет, т.к. я уже им не пользуюсь (из-за android 6.0, в нём нет поддержки open-ssl на которых работает indy)
     
     
  11. Like
    Alisson R Oliveira отреагировална Rusland в TMapsEngine   
    enatechno, kitty спасибо. Уже выложили. 
     
    Даже ZuBy там засветился c TMapsEngine  
  12. Like
    Alisson R Oliveira отреагировална Равиль Зарипов (ZuBy) в SuperObject vs JSON   
    Привет Всем!
     
    Решил поделится впечатлениями по работе с SuperObject'ом и родным JSON'ом
     
    тест был файла с 2000+ объектами в JSON файле
    структура файла была такая
    { "status":"OK", "last_id":"711", "objects":[ { "obj_id":"1", "obj_acc_id":"1", "obj_cat_id":"24", "obj_title":"13 магистраль", "obj_descr":"ЖК представляет собой комфортный дом, состоящий из 14 блок-секций (подъездов). Расположен в перспективном развивающемся районе по 13 Магистрали с удобным выездом как на левый берег, так и в старую часть города. Вблизи Жилого комплекса распологается новая школа, парк отдыха и культуры.", "obj_address":"ул. Мамышулы - 104, д. 16\/1", "obj_address2":null, "obj_url":"3fa07dd73be072b049529c80c7d74732", "obj_planet":"1", "obj_country":"1", "obj_region":"1", "obj_city":"292", "obj_lat":"51.141", "obj_lon":"71.4835", "obj_insert_dt":null, "obj_update_dt":null, "obj_editted":"0", "obj_updated":"0", "obj_deleted":"0", "obj_showed":"1", "obj_rating":"0", "obj_pro_top":"0", "obj_pro_selected":"0", "obj_pro_unix_dt":"0", "obj_partner":"0", "obj_parent_id":"0", "obj_has_child":"0", "obj_currency":"0" }, // тут далее 2000+ объектов ] } SuperObject  Время выполнения:  ~01:393
    JSON родной Время выполнения: ~01:690
     
    разница не особо ощутима, тем более если будет меньше объектов
     
    JSON родной
    function JSONParse(const aJSONData: string; const aMemo: TMemo): boolean; var aJSValue: TJSONValue; aJSObject, aJSObjArr: TJSONObject; aJSArray: TJSONArray; I: integer; begin Result := false; aJSValue := TJSONObject.ParseJSONValue(aJSONData) as TJSONValue; if Assigned(aJSValue) then begin aJSObject := aJSValue as TJSONObject; aMemo.Lines.Add('status: ' + aJSObject.GetValue('status').Value); if aJSObject.GetValue('status').Value = 'OK' then begin Result := true; if Assigned(aJSObject) then begin aJSArray := aJSObject.GetValue('objects') as TJSONArray; if Assigned(aJSArray) then begin Result := true; aMemo.Lines.Add('last_id: ' + aJSObject.GetValue('last_id').Value); aMemo.Lines.Add('count: ' + aJSArray.Count.ToString); for I := 0 to aJSArray.Count - 1 do begin aJSObjArr := aJSArray.Items[I] as TJSONObject; if Assigned(aJSObjArr) then begin aMemo.Lines.Add(aJSObjArr.GetValue('obj_id').Value + ',' + aJSObjArr.GetValue('obj_acc_id').Value + ',' + aJSObjArr.GetValue('obj_cat_id').Value); aMemo.Lines.Add(aJSObjArr.GetValue('obj_title').Value); aMemo.Lines.Add(aJSObjArr.GetValue('obj_descr').Value); aMemo.Lines.Add(aJSObjArr.GetValue('obj_address').Value); aMemo.Lines.Add(aJSObjArr.GetValue('obj_url').Value); end; end; end; end; end; aJSValue.Free; end; end; SuperObject
    function JSONSOParse(const aJSONData: string; const aMemo: TMemo): boolean; var xObject: ISuperObject; xCount, I: integer; sfmt: string; begin Result := false; xObject := SO(aJSONData); aMemo.Lines.Add('status: ' + xObject['status'].AsString); if xObject['status'].AsString = 'OK' then begin Result := true; xCount := xObject['objects'].AsArray.Length; aMemo.Lines.Add('count: ' + xCount.ToString); aMemo.Lines.Add('last_id: ' + xObject['last_id'].AsInteger.ToString); for I := 0 to xCount - 1 do begin aMemo.Lines.Add(xObject['objects[' + I.ToString + ']."obj_id"'].AsInteger.ToString + ',' + xObject['objects[' + I.ToString + ']."obj_acc_id"'].AsInteger.ToString + ',' + xObject['objects[' + I.ToString + ']."obj_cat_id"'].AsInteger.ToString); aMemo.Lines.Add(xObject['objects[' + I.ToString + ']."obj_title"'].AsString); aMemo.Lines.Add(xObject['objects[' + I.ToString + ']."obj_descr"'].AsString); aMemo.Lines.Add(xObject['objects[' + I.ToString + ']."obj_address"'].AsString); aMemo.Lines.Add(xObject['objects[' + I.ToString + ']."obj_url"'].AsString); end; end; end; Разница ощутима когда пишешь код, SO намного легче читать
     
    Подробней почитать и скачать SO
  13. Like
    Alisson R Oliveira отреагировална Andrey Efimov в Как получить имя владельца устройства на андроиде   
    Посмотрел.
    В Андроид АПИ это поле вроде как не описано, но в исходниках Андроида оно есть, правда приватное, называется LOCK_SCREEN_OWNER_INFO (тип string).
    В интернете нашёл вот такое решение (не проверял):
    Settings.Secure.getString(getActivity().getContentResolver(), Settings.Secure.LOCK_SCREEN_OWNER_INFO); Если не заработает, то 99%, что извлечь вообще не получится.
     
    p.s. Посмотрел ещё раз АПИ, скорее всего решение не рабочее, т.к. поля "Settings.Secure.LOCK_SCREEN_OWNER_INFO" попросту нет в АПИ, а значит возникнет ошибка уже на стадии написания кода.
  14. Like
    Alisson R Oliveira отреагировална Andrey Efimov в Как вызвать что-нибудь из Android API? Объясните пошагово   
    Кто ищет, тот найдёт...
    Вот вы статью нашли, полазили бы в блоге, например в разделе "Список всех сообщений" и ...
    Как создавать обёртки для JAVA-кода Как подключить и использовать свой JAVA-класс Как добавить jar библиотеку в проект Дальше, воспользовались бы поиском на этом форуме и ...
    Поиск по запросу "обёртки":
    Утилита генерации pas файлов для AndroidAPI из jar файлов + ещё множество полезных тем Ну и наконец: Полностью транслированное Android API 7-23 уровня
    И чуть не забыл, есть же справка официальная Help for RAD Studio Berlin
     
    p.s. Всё уже давно разжёвано, вопросы задают по каким-то конкретным моментам.
  15. Like
    Alisson R Oliveira отреагировална Равиль Зарипов (ZuBy) в Вызвать настройки GPS в Android   
    интентом вызывается, вот так
    procedure TForm4.GPSSettings; {$IFDEF ANDROID} var Intent: JIntent; {$ENDIF} begin {$IFDEF ANDROID} Intent := TJIntent.Create; Intent := TJIntent.JavaClass.init(TJSettings.JavaClass.ACTION_LOCATION_SOURCE_SETTINGS); TAndroidHelper.Activity.startActivity(Intent); {$ENDIF} end;  
  16. Like
    Alisson R Oliveira отреагировална Евгений Корепов в OnUpdateObjects выполняется дважды   
    Если вы понаблюдаете дальше, то обнаружите что выполняется гораздо больше раз. Попробуйте к примеру повернуть устройство горизонтально, потом опять вертикально - еще пара выполнений. 
    OnUpdateObjects и OnUpdatingObjects выполняется постоянно - при изменении размеров,  скрытии и повторном показе, переключении приложений и т.д. В справке так и написано "Occurs immediately after the list view component is updated."
    Так что надо придерживаться двух правил :
    1. При добавлении/изменении TListViewItem отключайте обработку вышеуказанных процедур. 
    Setting.Flags.ListViewUpdating:=True; // Глобальная переменная или ListView.OnUpdatingObjects:=nil; AItem:=ListView.Items.Add; AItem.Data['Type']:='MySuperPuperItem'; AItem.Data['Name']:=AName; AItem.Data['Value']:=AValue; Setting.Flags.ListViewUpdating:=False; // Глобальная переменная или ListView.OnUpdatingObjects:=ListViewUpdatingObjects; AItem.Adapter.ResetView(AItem); // принудительно вызываем ListViewUpdatingObjects ... procedure TFormMain.ListViewUpdatingObjects(const Sender: TObject; const AItem: TListViewItem; var AHandled: Boolean); begin if Setting.Flags.ListViewUpdating then // Если используете глобальную переменную Exit; ... 2. Внутри OnUpdateObjects и OnUpdatingObjects при добавлении TListItemText и прочих элементов, проверяйте их существование, возможно они уже были добавлены вашим кодом ранее.
  17. Like
    Alisson R Oliveira отреагировална Равиль Зарипов (ZuBy) в Наклеить одно изображение на другое   
    var bmp: TBitmap; SrcRect, DstRect, SrcRect2, DstRect2: TRectF; begin bmp := TBitmap.Create(256, 256); bmp.Canvas.BeginScene(); try SrcRect := TRectF.Create(0, 0, 256, 256); DstRect := TRectF.Create(20, 20, 236, 236); SrcRect2 := TRectF.Create(0, 0, 256, 256); DstRect2 := TRectF.Create(0, 0, 256, 256); bmp.Clear(TAlphaColorRec.Null); bmp.Canvas.DrawBitmap(Image1.Bitmap, SrcRect2, DstRect2, 0.8, false); bmp.Canvas.DrawBitmap(Image2.Bitmap, SrcRect, DstRect, 0.8, false); finally bmp.Canvas.EndScene(); Image3.Bitmap.SetSize(256, 256); Image3.Bitmap.CopyFromBitmap(bmp); bmp.Free; end; end;  
  18. Like
    Alisson R Oliveira отреагировална FeLDMARShaL в Изменение стиля TfgActivityDialog №2   
    Коллеги. Я верю в коллективный разум. Требуется изменить визуально индикатор прогресса. Для этого к проекту необходимо подгружать стили. За основу я взял тему http://manjunath4android.blogspot.ru/2015/12/display-progress-dialog-without-text.html
    Будем менять индикатор на тот который указан в теме. Что было сделано с моей стороны:
    1) Прилинковал все необходимые фалы к нашему проекту
     
    2) Проконсультировался с разработчиком компонентов  Полазил по исходникам, в результате чего понял что поменять стиль в текущей реализации уже должно получится. Для этого есть 2 свойства у класса TfgActivityDialog: Theme и ThemeID.
    Если со свойством Theme все понятно, его необходимо задать как TfgDialogTheme.Custom, то с ThemeID не так все просто. На просторах интернета нашел что это такое (R.layout.my_progress) и вроде бы  даже перевел на Pascal: TAndroidHelper.Context.getResources.getIdentifier(StringToJString('my_progress'), StringToJString('layout'), TAndroidHelper.Context.getPackageName), но в конечном итоге имеем вот это:

    А ожидается вот это:

     
    На кнопку которая должна отобразить индикатор активности повесил вот такой код:
    procedure TmainForm.Button1Click(Sender: TObject); var fg: TfgActivityDialog; themId: Integer; begin themId := TAndroidHelper.Context.getResources.getIdentifier(StringToJString('my_progress'), StringToJString('layout'), TAndroidHelper.Context.getPackageName); fg := TfgActivityDialog.Create(Self); try if themId<>0 then begin fg.Theme := TfgDialogTheme.Custom; fg.ThemeID := themId; fg.Title := 'Title'; fg.Message := 'Message'; Button1.Text := 'TfgDialogTheme.Custom' end else Button1.Text := 'TfgDialogTheme.Auto'; fg.Show; sleep(3000); fg.Hide; finally FreeAndNil(fg); end; end;  
  19. Like
    Alisson R Oliveira отреагировална Равиль Зарипов (ZuBy) в TMapsEngine   
    Компонент TMapsEngine
     
    Возможности
    Нативный LocationSensor [ANDROID] Геокодинг/Реверс геокодинг через Google API, Yandex API, Here Maps API Построение маршрута через Google Distance API Расчет дистанции по прямой Совместим со стандартным компонентом TLocationSensor  
    Видео демонстрация
     
    На видео видно как TMapView косячик с миллионом точек, приложение зависло при отрисовке, но с этим ничего не поделать.
    Без синхронизации не возможно отрисовать все точки
     
    Исходник
    TMapsEngine_source.zip
    TMapsEngine_Seattle_10.zip
     
    Скачать APK  (долго он там не пролежит, а форум не позволяет загрузить zip размером 7,4 мб )
     
  20. Like
    Alisson R Oliveira отреагировална ENERGY в TListView Custom checkboxes (иконка чекбокс "избранное")   
    Огромное спасибо Равиль! Как хорошо что вы помогаете.
    Итак для тех кто не знает, в TListView есть режим DynamicAppearance , который позволяет добавлять предустановленные элементы - картинки, текст, GlyphButon. В хелпе  написано что их может быть любое количество.
    Итак добавляем TListView, в панели Structure  выбираем TListView > ItemAppearance > Item.
    В инспекторе объектов выбрать свойство Appearance и  комбобоксе Dynamic Appearance. Рядом в инспекторе появится свойство Objects - нажать на него и там уже добавляем нужные поля. Там же можно переименовать поле, в AppearanceObjectName чтобы позже использовать в RunTime. У меня периодически на этих этапах вылетает Catastrophic Failure и среду приходится терминировать с диспетчера (Berlin Update 2).
    Дальше, жмем правой кнопкой мыши по ListView и выбираем Toggle Design Mode, где можно увидеть эти добавленные Custom поля и расставить их мышкой и указать выравнивание.
    Это имя затем можно использовать в Runtime, для картинки это индекс в ImageList, который нужно указать в ListView  таким образом (за это еще раз спасибо Равилю! :), почему это сделали так неочевидно и почему это не указано в мануале, остается загадкой.. 
    Для TImageObjectAppearance с именем Star - 
    ListView1.Items.Add.Data['Star'] := Integer(1);
    Например заполняем список с картинками с индексами 0 и 1:
    procedure TForm5.FormShow(Sender: TObject); var   I: Integer; begin   for I := 0 to 9 do   begin     with ListView1.Items.Add do     begin       Text := 'Item ' + I.ToString;       Data['Star'] := Integer(I mod 2 = 0);     end;   end; end; Переключаем с картинки с индексом 1 на 0 и наоборот. procedure TForm5.ListView1ItemClick(const Sender: TObject; const AItem: TListViewItem); begin   AItem.Data['Star'] := AItem.Data['Star'].AsInteger xor 1; end ;
     
     
     
  21. Like
    Alisson R Oliveira отреагировална Равиль Зарипов (ZuBy) в TListView Custom checkboxes (иконка чекбокс "избранное")   
    как-то так, но это наверное сложно для понимания)
    LVStars.rar
  22. Like
    Alisson R Oliveira отреагировална ENERGY в Как сделать аналог Autosize в TImage   
    Равиль огромное вам спасибо, так просто. Все работает. Обычная пропорция.
    Я думал сложнее (я делал  Image1.Height := Image1.Bitmap.Height; ). И заодно решилась проблема, когда увеличиваешь размер формы, картинка корректно увеличивается с Fit. 
    Вот правильный код, который посоветовал Равиль:
     
    procedure TfrmSplash.FormResize(Sender: TObject); var   vKoef: Single; begin if Handle = nil then exit; // on Android without this user will get Access Violation   vKoef := Image1.Width / Image1.Bitmap.Width;   Image1.Height := Image1.Bitmap.Height * vKoef; end  
  23. Like
    Alisson R Oliveira отреагировална Равиль Зарипов (ZuBy) в Как сделать аналог Autosize в TImage   
    как то так наверное
    AutoSizeImage.rar
×
×
  • Создать...