-
Постов
568 -
Зарегистрирован
-
Посещение
-
Победитель дней
57
Сообщения, опубликованные ENERGY
-
-
Цитата
подпись слева (в левой колонке TLabel) и в правой колонке компоненты редактирования (TEdit, TComboBox и другие).
В мобильных приложениях надо экономить место. Поэтому лэйбл положите прямо внутрь Tedit и TCombobox или Memo (можно сделать в инспекторе объектов), поставьте ему enabled := false чтобы он был серого цвета. Затем на OnChange или OnChangeTracking проверяйте кол. символов и прячьте лэйбл:
Label1.Visible := Edit1.Text.Length = 0;
-
Цитата
Но, как я понял, мои ответы отправляются в пустоту без попыток осмысления
Я все внимательно читаю, просто думал вы про Design Time говорите.
Исправил на вариант без тэга.
Но имя все равно используется чтобы идентифицировать слой, но уже стало гораздо легче .
vDest := Self.Destination.Add;
vLayer := vDest.Layers.Add;
vLayer.SourceRect.Rect := TRectF.Create(TPoint.Zero, vSource.MultiResBitmap.Width,
vSource.MultiResBitmap.Height);
vLayer.Name := vSource.Name;
Result := vDest.Index; -
chaplin.u@gmail.com
Это они говорят "спасибо за важную информацию".
-
@RoschinSpb
ЦитатаЕще раз обращаю внимание: обязательный идентификатор инициализируется значением по умолчанию. по сути он и является опциональным.
По сути он как раз является обязательным, потому что при добавлении картинки в список в runtime, нужно указывать уникальное имя, притом в двух местах. Было бы классно, если бы компонент сам создавал это имя (в Runtime), конечно было бы удобней если имя было представлено как необязательное поле Description.
ЦитатаИспользование Tag мало того, что просто дурной тон, оно еще и лишнее и снижает базовую функциональность.
Ну без Tag пришлось бы вводит переменную-счетчик в класс текущей формы, что имхо только усложняет. А если форм несколько?
Использовать глобальную переменную, тоже вариант, но это же костыль, такой же как и тэг. А если используются костыли, в таком простой случае, значит что-то не так..ЦитатаИ вообще мне странно, что Вы сначала жалуетесь, на излишнюю сложность и уже на следующей строке перекладываете на программиста куда более сложную задачу (формировать отдельные списки/структуры).
Это имя нужно только компоненту TImageList. А юзеру чтобы отличать картинки в DesignTime в ImageList достаточно посмотреть на картинку. В остальных случаях - обращение через индексы.
Туда не запишешь какое то серьезное описание. Как вы представляете это? Одни значения для обрабатываемой картинки (размер, имя, разрешение, и многое др.) храним и читаем со специально созданного для этого класса, а описание\имя читаем с ImageList?
Это же не удобно и запутает. Плюс ImageList находится в юните GUI, где только GUI код,
а вся логика работы обычно в отдельном классе ядра и к тому же код может быть мультипоточный.
Плюс обычно если программисту нужно хранить описание картинки или имя, то оно должны быть writeable. А в ImageList оно readonly.
Имхо это велосипед, явно усложняющий работу.
Цитатаа при чем здесь StringList, здесь больше уместна аналогия с TComponent.Name.
Какая разница какой тип данных содержит список - строки, картинки - это просто data куски лежащие в памяти.
ЦитатаЕсли же речь идет о динамической загрузке, это почти всегда что-то нестандартное, тут уже возможны всякие варианты
Есть определенные стандарты написания похожих компонентов, втч. это и имена методов (Add, Remove, Insert etc), имхо разработчикам следовало бы держаться стандартов Delphi для списков, к которым за годы все привыкли.
-
다음은 listview에서 이미지 URL을 사용하는 방법에 대한 정보입니다 (직원 이미지 저장소가있는 MYSQL 데이터베이스).
https://forums.embarcadero.com/message.jspa?messageID=687990
그리고 또 하나 firemonkey로 FireDAC를 사용하여 BLOB 필드를 읽고 쓰는 법
-
Цитата
Вы бы смогли догадаться, что изображено на этих картинках без доп. описания? Картинки конечно неважные, но в коде-то Вы их вообще не видите.
Имена можно было ввести, но опционально (description) - нужно юзеру, - добавил. Не нужно ну и не надо.
В большинстве случаев описание не нужно. А те кому это нужно, обычно хранят это в своих структурах, в отдельном списке, где можно кроме описания, сохранить и др. параметры (путь к файлу, адрес итд).
А сейчас это обязательный идентификатор, который, имхо, усложняет работу со списком..
ЦитатаДопустим в приложении появилась вторая, третья, N+1 форма. Я не знаю отнаследовалась она, или просто скопипастилась, или Вы что-то добавили в Design-Time, так или иначе есть ненулевая вероятность получить неоднократное добавление одного и того же
Ну и что, это задача уже ложиться на программиста, причем здесь ImageList.
Можно и не замещать, а просто добавить новую картинку, с тем же именем или игнорировать добавление. Как например в StringList сделано. Там по умолчанию выключено определение дубликатов и добавляется новая строка.. Представьте если бы StringList по умолчанию возбуждал исключение на дубликат строки, весело было бы..
-
@RoschinSpb
ЦитатаИспользование Tag, как бы намекает Не стоит скрывать свойство TCustomSourceItem.Name от пользователя, пусть сам заботится об уникальности (не такая уж это большая проблема).
Я честно говоря вообще не понимаю зачем туда ввели строковые имена и зачем они пользователю сдались. Индексов хватило бы с головой и быстрее бы работало - не нужно перебирать компаратором все эти массивы строк, и меньше бы памяти брало.
ЦитатаЭто свойство может быть использовано для предотвращения случайной повторной загрузки, допустим если есть картинка с указанным названием поднимать исключение.
И это я тоже не понимаю, зачем нужно делать исключение на этот случай, по идее нужно было молча заменить картинку.
У Delphi есть широкий выбор разнообразных списков, очередей, cтэков, массивов, деревьев и никогда в них не использовались имена. Для идентификации и унификации всегда использовалось число-индекс. У этого подхода гораздо больше плюсов, чем у строковых идентификаторов, почему решили отойти от этого стандарта, не понимаю...
-
type TImageListHelper = class helper for TImageList function Add(aBitmap: TBitmap): integer; end; function TImageListHelper.Add(aBitmap: TBitmap): integer; const SCALE = 1; var vSource: TCustomSourceItem; vBitmapItem: TCustomBitmapItem; vDest: TCustomDestinationItem; vLayer: TLayer; begin Result := -1; if (aBitmap.Width = 0) or (aBitmap.Height = 0) then exit; // add source bitmap vSource := Source.Add; vSource.MultiResBitmap.TransparentColor := TColorRec.Fuchsia; vSource.MultiResBitmap.SizeKind := TSizeKind.Source; vSource.MultiResBitmap.Width := Round(aBitmap.Width / SCALE); vSource.MultiResBitmap.Height := Round(aBitmap.Height / SCALE); vBitmapItem := vSource.MultiResBitmap.ItemByScale(SCALE, True, True); if vBitmapItem = nil then begin vBitmapItem := vSource.MultiResBitmap.Add; vBitmapItem.Scale := Scale; end; vBitmapItem.Bitmap.Assign(aBitmap); vDest := Destination.Add; vLayer := vDest.Layers.Add; vLayer.SourceRect.Rect := TRectF.Create(TPoint.Zero, vSource.MultiResBitmap.Width, vSource.MultiResBitmap.Height); vLayer.Name := vSource.Name; Result := vDest.Index; end;
Хелпер позволяет добавлять свои методы, не наследуясь от класса.
После этого можно обращаться к любому ImageList
ImageList1.Add(MyBitmap);
-
Не нашел я к сожалению в этой и других ветках простой код для добавления TBitmap в ImageList без лишних элементов. Все приходиться делать самому:
Helper для ImageList
type TImageListHelper = class helper for TImageList function Add(aBitmap: TBitmap): integer; end; function TImageListHelper.Add(aBitmap: TBitmap): integer; const SCALE = 1; var vSource: TCustomSourceItem; vBitmapItem: TCustomBitmapItem; vDest: TCustomDestinationItem; vLayer: TLayer; begin Result := -1; if (aBitmap.Width = 0) or (aBitmap.Height = 0) then exit; // add source bitmap vSource := Source.Add; vSource.MultiResBitmap.TransparentColor := TColorRec.Fuchsia; vSource.MultiResBitmap.SizeKind := TSizeKind.Source; vSource.MultiResBitmap.Width := Round(aBitmap.Width / SCALE); vSource.MultiResBitmap.Height := Round(aBitmap.Height / SCALE); vBitmapItem := vSource.MultiResBitmap.ItemByScale(SCALE, True, True); if vBitmapItem = nil then begin vBitmapItem := vSource.MultiResBitmap.Add; vBitmapItem.Scale := Scale; end; vBitmapItem.Bitmap.Assign(aBitmap); vDest := Destination.Add; vLayer := vDest.Layers.Add; vLayer.SourceRect.Rect := TRectF.Create(TPoint.Zero, vSource.MultiResBitmap.Width, vSource.MultiResBitmap.Height); vLayer.Name := vSource.Name; Result := vDest.Index; end;
Хелпер позволяет добавлять свои методы, не наследуясь от класса.
После этого можно обращаться к любому ImageList
ImageList1.Add(MyBitmap);
-
Евгений Корепов
https://forums.embarcadero.com/thread.jspa?threadID=248231&tstart=0
https://forums.embarcadero.com/thread.jspa?threadID=248237&tstart=0
https://quality.embarcadero.com/browse/RSP-17162
Плюс там
1. Application lost all effects...glow effects on buttons etc.
2. TAniIndicator for example does work anymore.
3. Simple TEdit is very slow in response.
4. TListBoxes are very slow. Enabling and disabling TListBoxItems takes seconds to complete, leaving the application useless.
5. The memory consumption seems higher than the Berlin compiled version.
6. FormShow and FormActivate is called when the Android splash is still showing. I still have no idea when the for is actually showing!
7. Tab transistions is not happening at all.
8. Application crashed after a while of waiting for some TListboxItems to appear. (10 of them)Марко в своем блоге подтвердил: "issues with animation on Android are being investigated. Probably related with the changes in threading model".
-
На всех Android версиях от 4.0.4 до 7. На процессорах ARMv7. Также работает на Intel (Atom) процессорах через эмулятор ARM который разрабатывает Intel - libhoudini обычно уже сразу установлен в таких девайсах.
Также работает на процессорах ARMv8 (x64) т.к. они поддерживают инструкции ARMv7.
По факту это наибольший сегмент мобильных устройств. Втч это Android Wear, Google Glass, разные Smart TV, Amazon FireTV, Amazon FirePhone, BlackBerry, см. статью.
Не работает на ARMv6 и ниже довольный старый сегмент девайсов, ~2010, там и Android второй версии. Aндроид меньше 4 используют около ~1% девайсов сейчас (статистика).
http://docwiki.embarcadero.com/PlatformStatus/en/Main_Page
Интересная статья:
-
Что там новенького ? Поломанная платформа Android из за многократного падения производительности?
-
Правая кнопка мыши по вкладке и Close Page = Apply.
RoschinSpb в Berlin update 2 нет этой кнопки.
-
Проблема в стиле. Если его удалить, или загрузить другой то все работает.
Загрузите любой стиль например c:\Users\Public\Documents\Embarcadero\Studio\18.0\Styles\Win10Modern.Style и используйте его или если нужен свой, то посмотрите как там делается menuitemstyle.
Там TLayout - со Stylename = glyph и на нем лежит TGlyph с Stylename - glyphstyle.
-
-
Pax Beach
Т.е. для шестого Android нужно запрашивать права на камеру дополнительно? Даже если они уже указаны в Permissionss?
-
Если кто то хочет проэмулировать данную проблему, используйте эмулятор Nox. Он основан на Intel архитектуре и именно поэтому самый быстрый среди всех эмуляторов. Delphi программы на нем работают. И там та же проблема с заголовком.
Автор переименуйте пожалуйста тему на Смещается заголовок на Android Intel или что то похожее
-
Большое спасибо за помощь, добрый человек!
Еще добавлю, чтобы сменить фон Item'a (например на прозрачный) или добавить какие то рюшечки (например полоски между пунктами), на вышеуказанном примере: нужно зайти в стили, и редактировать imagesui.png файл который находится внутри контейнера listviewstyle_panel (не снаружи, т.к. там есть точно такой же). Т.е. жмем на imagesui.png > MultiresBitmap > выбираем нужный, и слева в инспекторе объектов жмем свойство Bitmap с помощью которого этот файл можно сохранить,(а потом и загрузить) на диск.
-
Огромное вам спасибо. Разобрался за несколько минут.
Вопрос:
1. Что делать, если нужно загружать туда фотографии с диска, они большого размера, грузить их в TimageList займет много ресурсов - туда разве что можно загрузить превью фотографии, да и превью хотелось бы загружать по потребности.
Насколько я понимаю в FMX TLIstView нету режима виртуального списка, когда нужно отрисовывать только видимые Items как было в VCL? Я поискал, вроде стандартного механизма нет.
Есть идея отнаследоваться от TImageList и сделать чтобы он подгружал нужные фотки, по мере запроса... Будет этакий кэширующий виртуальный TImageList .
2. Вы не задумывались создать в QC предложение с улучшенным TListView? Возможно добавят? Ведь вас уже рекламируют http://www.fmxexpress.com/very-customizable-listview-control-for-firemonkey-in-delphi-10-berlin-on-android-and-ios/
2. Кстати много вылезает предупреждений и подсказок от компилятора, тут два варианта или забить их директивами в самом модуле ListView
{$WARN OFF}
Или откомпилировать в dcu.
[dcc32 Warning] FMX.ListView.pas(866): W1045 Property declaration references ancestor private 'TListViewBase.FSeparatorLeftOffset' [dcc32 Warning] FMX.ListView.pas(868): W1045 Property declaration references ancestor private 'TListViewBase.FSeparatorRightOffset' [dcc32 Warning] FMX.ListView.pas(871): W1045 Property declaration references ancestor private 'TListViewBase.FHorizontal' [dcc32 Warning] FMX.ListView.pas(872): W1045 Property declaration references ancestor private 'TListViewBase.FMakeSelectedItemVisible' [dcc32 Warning] FMX.ListView.pas(872): W1045 Property declaration references ancestor private 'TListViewBase.FMakeSelectedItemVisible' [dcc32 Warning] FMX.ListView.pas(874): W1045 Property declaration references ancestor private 'TListViewBase.FTopOffset' [dcc32 Warning] FMX.ListView.pas(875): W1045 Property declaration references ancestor private 'TListViewBase.FBottomOffset' [dcc32 Warning] FMX.ListView.pas(876): W1045 Property declaration references ancestor private 'TListViewBase.FAutoColumns' [dcc32 Warning] FMX.ListView.pas(877): W1045 Property declaration references ancestor private 'TListViewBase.FColumns' [dcc32 Warning] FMX.ListView.pas(878): W1045 Property declaration references ancestor private 'TListViewBase.FMarg' [dcc32 Warning] FMX.ListView.pas(879): W1045 Property declaration references ancestor private 'TListViewBase.FColumnWidth' [dcc32 Warning] FMX.ListView.pas(882): W1045 Property declaration references ancestor private 'TListViewBase.FShowScrollBar'
-
Подскажите пожалуйста как реализовать такую вещь. Горизонтальный TListView где каждый Item это картинка, рястянутая целиком на Item.
Я попробовал использовать компонент Равиля, за что ему больше спасибо!
Никак не пойму (относительно недавно пришел с VCL) как нарисовать картинку целиком на Item на этом горизонтальном Item.
Это через стили надо делать? У ListView же какие то специальные стили, они отличаются например от стилей ListBox. Жаль там нет ItemOwnerDraw как в VCL. Пытался разобрать код в AutoColumns в проекте Равиля, но не разобрался, там рисуется колонками и список совсем другого типа..
Также еще один ньюанс не знаю даже как подойди к нему, между Items нужно сделать полоску конкретного цвета. Это в стилях по идее, левый и правый края Item закрасить надо?
Спасибо, очень надеюсь. Нигде нет нормальной инфы по горизонтальным спискам..
-
5 часов назад, Равиль Зарипов (ZuBy) сказал:
Не будем разбирать конкретно этот случай, пока Токио очень сырой.
Сломали всё что можно было. (обсуждали в чате)
Чтобы не плодить темы на форуме, вернитесь на Берлин апдейт 2, до какого нить хот-фикса от Ембы.
Что ж вы такое интересное в чате обсуждаете, это же тема не на один час, и даже не на месяц. Могли бы и тему создать. Наверное потому что бот Ярослава постит и закрывает темы, так можно было в той же теме (Whats New in Tokyo) по обсуждать. @brovin-yaroslav это вам на заметку, большая просьба не закрывать темы-новости.
-
Сделал решение для описанного выше варианта.
Добавил его на Stackoverflow
unit Misc.Android; interface uses SysUtils, Androidapi.JNI.GraphicsContentViewText, Androidapi.Helpers, Androidapi.JNI.JavaTypes, Androidapi.JNIBridge, Androidapi.JNI.Provider; type TGallery = class public class function GetLastImageID: integer; class function GetNextImageIDFromID(aFromID: integer; out aImagePath: string): integer; class function DeleteImageByID(aID: integer): boolean; end; implementation const _ID = '_id'; // TJBaseColumns.JavaClass._ID // uri in Androidapi.JNI.Provider { TGallery } {If you're using action TakePhotoFromCameraAction remember to set NeedSaveToAlbum to true. It does not work, because of Android problems, but it can work in future.} class function TGallery.GetLastImageID: integer; var vContent: JContentResolver; vValues: TJavaObjectArray<JString>; vOrderBy: JString; vCursor: JCursor; begin Result := -1; vContent := TAndroidHelper.Activity.getContentResolver; vValues := TJavaObjectArray<JString>.Create(1); vValues[0] := TJBaseColumns.JavaClass._ID; vOrderBy := StringToJString(_ID + ' DESC'); vCursor := vContent.query(TJImages_Media.JavaClass.EXTERNAL_CONTENT_URI, vValues, nil, nil, vOrderBy); try if vCursor.moveToFirst then Result := vCursor.getInt( vCursor.getColumnIndex(TJBaseColumns.JavaClass._ID) ); finally vCursor.close; end end; // Result is next Image ID and its aImagePath - is path to jpg image class function TGallery.GetNextImageIDFromID(aFromID: integer; out aImagePath: string): integer; var vContent: JContentResolver; vValues: TJavaObjectArray<JString>; vFilter: JString; vOrderBy: JString; vArgs : TJavaObjectArray<JString>; vCursor: JCursor; begin Result := -1; aImagePath := ''; vContent := TAndroidHelper.Activity.getContentResolver; vValues := TJavaObjectArray<JString>.Create(2); vValues[0] := TJMediaStore_MediaColumns.JavaClass.DATA; vValues[1] := TJBaseColumns.JavaClass._ID; // vValues[1] := TJMediaStore_MediaColumns.JavaClass.SIZE; // vValues[1] := TJImages_ImageColumns.JavaClass.DATE_TAKEN; vOrderBy := StringToJString(_ID + ' DESC'); vFilter := StringToJString(_ID + '>?'); vArgs := TJavaObjectArray<JString>.Create(1); vArgs[0] := StringToJString(aFromID.ToString); vCursor := vContent.query(TJImages_Media.JavaClass.EXTERNAL_CONTENT_URI, vValues, vFilter, vArgs, vOrderBy); try if (vCursor.getCount > 0) and vCursor.moveToFirst then begin Result := vCursor.getInt( vCursor.getColumnIndex(TJBaseColumns.JavaClass._ID) ); // vCursor.getLong(imageCursor.getColumnIndex(MediaStore.Images.Media.DATE_TAKEN)); //vSize := wCursor.getLong(wCursor.getColumnIndex(TJMediaStore_MediaColumns.JavaClass.SIZE)); aImagePath := JStringToString(vCursor.getString( vCursor.getColumnIndex(TJMediaStore_MediaColumns.JavaClass.DATA) )); end; finally vCursor.close; end; end; class function TGallery.DeleteImageByID(aID: integer): boolean; var vContent: JContentResolver; begin vContent := TAndroidHelper.Activity.getContentResolver; Result := vContent.delete(TJImages_Media.JavaClass.EXTERNAL_CONTENT_URI, StringToJString(_ID + '=' + aID.ToString), nil) = 1; end; end.
-
Ну так сделайте что написано. Укажите Bundle ID в Version Info, ту строку что просит указать среда.
-
Спасибо большое. Но странно почему сам компонент не умеет это делать стандартными гестурами, с двумя пальцами.
Надо будет когда побольше времени появится, реализовать это.
Также есть еще пример как делать зум двумя пальцами в
\Samples\Object Pascal\Mobile Snippets\InteractiveGestures\ImageZoom\
Но там просто меняется высота и ширина компонента.
Как закрыть обычный MessageBox программно?
в Android
Опубликовано
Нужно закрывать обычный Messagebox если юзер ничего не нажимает через какой то интервал времени.
Как его закрыть? Может можно тапнуть программно? Или тапнуть куда то по форме (если тапнуть вне messagebox он тоже закрывается). Только вот как это сделать. В Windows я бы отправлял сообщения или эмулировал нажатие enter на клавиатуре при помощи keyboard_event, а вот что делать на Android?