Лидеры
Популярный контент
Показан контент с высокой репутацией 30.05.2016 во всех областях
-
можно просто кинуть в uses vkbdhelper с этого форума закрывает вопрос с клавиатурой что там настраивать, не понимаю, большинство родных приложений на андроиде ведет себя так же для перехода на следующий edit я использую во-первых ReturnKeyType=Next, во-вторых на OnKeyUp if key=vkReturn then edit2.setfocus4 балла
-
TNotificationCenter CancelNotification Непонятный параметр
Vitaldj и 2 других отреагировал Brovin Yaroslav за вопрос
Хорошая практика использования TNotificationCenter - это уведомление пользователя о событиях, когда ваше приложение свернуто или скрыто. Как только ваше приложение открыто, то считается, что пользователь прочитал в шторке о вашем сообщение и дальнейшая работа должна идти в своем приложении. Кстати, пара любопытных моментов. Если приложение открыто в iOS, то в шторке визуально не будет появляться ваше уведомление сверху в статус баре. iOS не позволяет удалить уведомление по одному, только все.3 балла -
Проблемы с отрисовкой
#WAMACO и ещё один отреагировал Евгений Корепов за вопрос
В приведенном коде процедура FormCreate: procedure TFormMain.FormCreate(Sender: TObject); begin Timer.Interval:=10; Хотя такой короткий не нужен для большинства случаев.2 балла -
Слишком большой размер приложения.
Andrey Efimov и ещё один отреагировал Vitaldj за вопрос
Как вариант пересмотрите uses во всех формах, поудалайте ненужные. Бывает кинул что нибудь на форму, не стал использовать, удалил, а в uses оно осталось и добавляет лишний вес.2 балла -
vkbdhelper - поднятие компонентов над клавиатурой
zairkz и ещё один отреагировал Равиль Зарипов (ZuBy) за вопрос
Обновленная версия для TPresentedScrollBox vkbdhelper_presentedscroll.zip2 балла -
TPresentedScrollBox
zairkz и ещё один отреагировал Равиль Зарипов (ZuBy) за вопрос
для TPresentedScrollBox'a исправленная версия vkbdhelper_presentedscroll.zip2 балла -
Основываясь на фразе "создании приложения только для Windows" Сама Embarcadero продолжает говорить, что под Windows ничего лучше VCL нет. Используя VCL вы можете задействовать все возможности, предоставляемые операционной системой. Если чего-то будет нехватать для работы (в чем я сомневаюсь, арсенал компонентов и контролов, созданных в рамках VCL, весьма обширен) - к вашим услугам полный набор WinAPI. Все VCL контролы основываются на вызовах WinAPI функций, что гарантирует (ну да, громко сказано, конечно) их быструю работу, поскольку она контролируется оптимальным кодом самой ОС. Помимо этого, некоторые задачи практически невозможно решить без задействования функций ОС. Например, хуки, сервисы, нестандартное поведение при движении мыши (WM_NCHITTEST)... Поведение контролов также будет 100% таким, как пользователь привык видеть во всех приложениях родной ОС. Да, на FMX тоже можно использовать функции ОС и нативные контролы. Но микс нативных и "собственных" контролов приводит к извращениям по расположению и компоновке контролов, т.к. нативный контрол всегда отрисуется поверх собственных. Также, т.к. Windows основана на механизме передачи оконных сообщений - есть определенные сложности в применении WinAPI. Ну и - если вы задействуете WinAPI функции, т.е. привяжетесь к конкретной ОС - смысл тогда использовать FMX? Резюмируя - если работа действительно планируется только под Windows - используйте VCL. Если хоть в отдаленном будущем мелькает возможность работы приложения на других платформах - то сразу нужно работать на FMX, этим вы избавите себя от проблем портирования приложения.2 балла
-
ITextActions не работают под Android
Rusland отреагировал asviridenkov за вопрос
Спасибо, я в итоге нашел как исправить - нужно при окончании выделения копировать его в FTextService.Text и плюс обязательна корректная реализация GetSelectionBounds. Но то, что оно не работает через ITextActions - не очень хорошо. Параллельно еще одна проблема выяснилась - невозможно показать контекстное меню, если нет клавиатуры на экране. В коде жестко зашито if TVirtualKeyboardState.Visible in VirtualKeyboardAndroid.VirtualKeyboardState then DoShowContextMenu; Это неправильно, т.к. не позволяет копировать текст из read-only контролов без показа клавиатуры, которая тут не нужна.1 балл -
Поправьте меня, если я неправ, plz. Просто очень сливаются два разных понятия. TPushNotification и TNotification Когда приходит push, ОС создает уведомление (Notification) в шторке. Далее, если программа запущена, то вызывается ее обработчик пушей. Если нет то пуши сидят где-то и ждут. Когда я запускаю программу, я просматриваю StartupNotifications - (это TPushNotification) ps:=AServiceConnection.Service; for LNotification in ps.StartupNotifications do и что-то делаю по пришедшим пушам, например, перехожу сразу на какую-то дальнюю форму... Далее мне хочется стереть соответствующее уведомление в шторке как отработанное. В известном примере стирают всё разом. TNotificationCenter.Create(NIL).CancelAll(); Но у класса есть метод TNotificationCenter.Create(NIL).CancelNotification(AName:String); Так вот, вопрос (добрался все-таки))) Как сопоставить TPushNotification и TNotification? Где взять AName?1 балл
-
Как сначала убрать Drawer а потом выполнять действие
Andrey Efimov отреагировал Brovin Yaroslav за вопрос
Если интересует определение момента полного закрытия TMultiView, то смотрите событие: OnStartHiding - начинает закрываться OnHidden - компонент закрылся OnStartShowing - начинает открываться OnShown - компонент открылся1 балл -
Слишком большой размер приложения.
Rusland отреагировал AndroidHalfNoob за вопрос
на планшете 4.0 на телефоне 4.2.2 и при этом на планшете размер установленной программы меньше1 балл -
TNotificationCenter CancelNotification Непонятный параметр
zairkz отреагировал Равиль Зарипов (ZuBy) за вопрос
т.к. Push нотификатор создаёт система, имя вы скорей всего никогда не узнаете. Да это и не нужно, т.к. должно быть логическое поведение. Если приложение открылось, то в шторке все должно скрыться, если информация важная отображайте её в приложении1 балл -
Имея SSD и столько памяти... еще бы он тормозил1 балл
-
Kitty, единственный способ работы - это использование сервиса, а, как я понял, в C++Builder их нет. Поэтому я вижу выход только в том чтобы написать прожку на Дельфи. Перейти не так сложно, как думаете. PS. По поводу перезапуска свернутого - у меня, например, в случае зависания программы (с сервисом) после рестарта она показывает только черный экран. Приходится заходить в Настройки -> Приложения -> искать свое приложение и делать Остановить. После этого запускается нормально. Собственно тоже не знаю как с этим бороться.1 балл
-
Смотрите в демках ScrollableForm. Еще вот эту ветку1 балл
-
TPresentedScrollBox
Kitty отреагировал asviridenkov за вопрос
К сожалению, даже подобные элементарные вещи в FMX надо делать руками. В станрартных примерах поставляемых с дельфи есть образец какой код надо писать, типа ScrollForm что-ли называется.1 балл -
Win 10 x64, 12 GB. Проекты вынес на SSD. При работе с проектами, выключаю антивирус, отключаю синхронизацию облака. Берлин компилит проекты под Android быстрее Сиэтла. Под Windows и так моментально. Никаких тормозов в работе часами не увидел.1 балл
-
Проблемы с отрисовкой
Rusland отреагировал Евгений Корепов за вопрос
Накидал примерный проект для корректной работы с потоками. Создаем поток, в который с помощью очереди закидываем задания и в таймере получаем результат выполнения. Вместо изжившего себя TIdHTTP, использовал THTTPClient (вдруг вам понадобится, к примеру, запускать это приложение на 6 андроиде и обращаться по https - Indy такое уже не сможет). Код юнита с потоком: unit UnitGetHttpThread; interface uses classes, SysUtils, System.Generics.Collections, System.SyncObjs, System.Net.HttpClient; type THTTPRec=record Command : String; Query : String; ErrorMsg : String; ErrorCode : Integer; Page : String; Stream : TMemoryStream; ItemImageIndex : Integer; end; THTTPThread=class(TThread) private FQueueRequest: TThreadedQueue<THTTPRec>; FQueueResult: TThreadedQueue<THTTPRec>; FHTTPRec: THTTPRec; function GetHTTP(AHTTPRec: THTTPRec) : THTTPRec; protected HTTPClient: THTTPClient; procedure Execute; override; public constructor Create(AQueueRequest, AQueueResult : TThreadedQueue<THTTPRec>); destructor Destroy; override; end; implementation constructor THTTPThread.Create(AQueueRequest, AQueueResult : TThreadedQueue<THTTPRec>); begin FreeOnTerminate:=False; FQueueRequest:=AQueueRequest; FQueueResult:=AQueueResult; HTTPClient:=THTTPClient.Create; Inherited Create(FALSE); end; destructor THTTPThread.Destroy; begin HTTPClient.Free; inherited Destroy; end; procedure THTTPThread.Execute; begin while Not Terminated do if FQueueRequest.PopItem(FHTTPRec) = TWaitResult.wrSignaled Then begin if FHTTPRec.Command.Equals('stop') then begin FHTTPRec.ErrorCode:=200; FHTTPRec.ErrorMsg:='Ok'; FQueueResult.PushItem(FHTTPRec); Continue; end; FHTTPRec.ErrorCode:=0; FHTTPRec.ErrorMsg:=''; FHTTPRec:=GetHTTP(FHTTPRec); if Not FHTTPRec.Command.Equals('error') then FQueueResult.PushItem(FHTTPRec); end; end; function THTTPThread.GetHTTP(AHTTPRec: THTTPRec) : THTTPRec; Var HTTPResponse: IHTTPResponse; begin try if AHTTPRec.Command.Equals('image') then begin HTTPResponse:=HTTPClient.Get(AHTTPRec.Query,AHTTPRec.Stream); AHTTPRec.ErrorCode:=HTTPResponse.StatusCode; AHTTPRec.ErrorMsg:=HTTPResponse.StatusText; end Else begin HTTPResponse:=HTTPClient.Get(AHTTPRec.Query); AHTTPRec.Page:=HTTPResponse.ContentAsString; AHTTPRec.ErrorCode:=HTTPResponse.StatusCode; AHTTPRec.ErrorMsg:=HTTPResponse.StatusText; end; except AHTTPRec.ErrorCode:=-1; AHTTPRec.ErrorMsg:='ErrorGetURL'; end; Result:=AHTTPRec; end; end. Код основной формы (основного потока): unit UnitFormMain; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, System.Generics.Collections, UnitGetHttpThread, FMX.Layouts, FMX.ListBox, System.JSON; type TFormMain = class(TForm) MainContentDownloadBaseListBox: TListBox; Timer: TTimer; procedure TimerTimer(Sender: TObject); procedure FormCreate(Sender: TObject); private { Private declarations } FQueueRequest: TThreadedQueue<THTTPRec>; FQueueResult: TThreadedQueue<THTTPRec>; HTTPThread : THTTPThread; public { Public declarations } procedure GetHTTP(ACommand : String; AListItemIndex : Integer; BaseID : String); procedure FillListBoxImage(AHTTPRec : THTTPRec); procedure FillListBoxItem(AHTTPRec : THTTPRec); end; var FormMain: TFormMain; implementation {$R *.fmx} procedure TFormMain.FormCreate(Sender: TObject); begin Timer.Interval:=10; FQueueRequest:=TThreadedQueue<THTTPRec>.Create(50, 1000, 10); FQueueResult:=TThreadedQueue<THTTPRec>.Create(50, 1000, 10); HTTPThread:=THTTPThread.Create(FQueueRequest,FQueueResult); GetHTTP('json', -1, ''); // запускаем карусель end; procedure TFormMain.TimerTimer(Sender: TObject); Var FHTTPRec : THTTPRec; begin while FQueueResult.PopItem(FHTTPRec) = TWaitResult.wrSignaled do begin if FHTTPRec.ErrorCode=200 then begin if FHTTPRec.Command.Equals('json') then FillListBoxItem(FHTTPRec); if FHTTPRec.Command.Equals('image') then FillListBoxImage(FHTTPRec); if FHTTPRec.Command.Equals('stop') then begin Timer.Enabled:=False; // AniIndicator.Visible:=False; // AniIndicator.Enabled:=False; end; end Else begin Timer.Enabled:=False; // AniIndicator.Visible:=False; // AniIndicator.Enabled:=False; // LabelTitle.Text:='Не удалось получить данные, проверьте подключение к Интернет.'; end; end; end; procedure TFormMain.FillListBoxItem(AHTTPRec : THTTPRec); Var JSON : TJSONObject; I : Integer; BaseName, BaseCaption, BaseCategory, BaseID, BaseData: String; Item, ItemRadio: TListBoxItem; begin JSON := TJSONObject.ParseJSONValue(AHTTPRec.Page) as TJSONObject; if Not Assigned(JSON) then Exit; for I:=0 To JSON.Count-1 do Begin BaseData := JSON.Pairs[i].ToString; BaseData := BaseData.Substring(pos('"', BaseData)); BaseName := BaseData.Remove(pos('"', BaseData) - 1); BaseData := BaseData.Substring(pos('"', BaseData)); BaseData := BaseData.Substring(pos(':', BaseData)); { JSON1 := TJSONObject.ParseJSONValue(BaseData) as TJSONObject; BaseCaption := JSON1.Values['caption'].Value; BaseCategory := JSON1.Values['category'].Value; BaseID := JSON1.Values['id'].Value; } if MainContentDownloadBaseListBox.Items.IndexOf(BaseID) = -1 then Begin Item := TListBoxItem.Create(Self); Item.Height := 120; Item.StyleLookup := 'ListBoxItemDownloadBaseStyle'; Item.Text := BaseID; Item.StylesData['name'] := BaseName; Item.StylesData['caption'] := BaseCaption; Item.StylesData['category'] := BaseCategory; GetHTTP('image', Item.Index, BaseID); // отсылаем в поток запрос на скачивание картинки MainContentDownloadBaseListBox.AddObject(Item); End; End; GetHTTP('stop', -1, ''); end; procedure TFormMain.FillListBoxImage(AHTTPRec : THTTPRec); begin MainContentDownloadBaseListBox.ListItems[AHTTPRec.ItemImageIndex].ItemData.Bitmap.LoadFromStream(AHTTPRec.Stream); end; procedure TFormMain.GetHTTP(ACommand : String; AListItemIndex : Integer; BaseID : String); Var FHTTPRec : THTTPRec; begin FHTTPRec.Page:=''; Timer.Enabled:=True; if ACommand='stop' then begin FHTTPRec.Command:='stop'; FQueueRequest.PushItem(FHTTPRec); end; if ACommand='json' then begin FHTTPRec.Command:=ACommand; FHTTPRec.Query:='https://ссылка получения json'; FQueueRequest.PushItem(FHTTPRec); end; if ACommand='image' then begin FHTTPRec.Command:=ACommand; FHTTPRec.Query:='https://ссылка получения картинки'+BaseID; FHTTPRec.ItemImageIndex:=AListItemIndex; FHTTPRec.Stream:=TMemoryStream.Create; FQueueRequest.PushItem(FHTTPRec); end; end; end. Одним потоком забираем все что нужно из сети - и json данные и картинки, ну и все что еще прикрутите.1 балл