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

При установки WordWrap у TListViewItem.Objects.Text неверно отображается текст в Android


BurcevD

Вопрос

Рекомендуемые сообщения

  • 0

сделай у TextObject'a VertAlign = Leading и задавай высоту итема по размеру текста

Пробовал делать, как вы сказали (про VertAlign), тогда артефакты будут только внизу, а размер мне необходим статический. В Win32 все работает нормально, хотелось бы также и на андроиде.

Ссылка на комментарий
  • 0

все просто. у тебя на винде шрифт 12 вот все и красиво рисуется ибо ты подобрал высоту итемов. под андроидом шрифт идет 16 если не задаешь по умолчанию по моему, вот текст у тебя и не влезает и переносится, а где переносится рисует вершки от новой строчки. 

 

тут или обработку вешаешь и увеличиваешь высоту итемов сам руками, либо задаешь шрифту размер руками.

Ссылка на комментарий
  • 0

Плюнул копаться в 10к строках кода ListView и написал свой листвью велосипед.

Хотя наверное в целом ListView достойный и вариативный компонент и я представляю проделанную работу его автора, но все равно не получается выполнить в нем все что хочется.

Ссылка на комментарий
  • 0

Копался, копался так ничего и не получилось, в итоге сделал как предложил ruslan (пост 4) но со своими доработками, если кому интересно

на создание объекта и на событие OnUpdatingObjects (на TListView) сделал

   aItem.Height := Round(CalculateTextHeight(aItem.Text, aItem.Objects.TextObject.Width, 36, 130, aItem.Objects.TextObject.Font))+4;
aItem - TListViewItem - элемент списка из TListView
 
сама функция вот
function CalculateTextHeight(aText: String; aWidth: Single; aMinHeight: Single = 0; aMaxHeight: Integer = 0; aFont: TFont) : Single;
begin
  FTextLayout.BeginUpdate;
  try
    FTextLayout.Text := aText;
    FTextLayout.MaxSize := TPointF.Create(aWidth, 1000);
    FTextLayout.WordWrap := True;
    FTextLayout.Font.Assign(aFont);
    FTextLayout.HorizontalAlign := FMX.Types.TTextAlign.Leading;
    FTextLayout.VerticalAlign := FMX.Types.TTextAlign.Leading;
  finally
    FTextLayout.EndUpdate;
  end;
  Result := FTextLayout.Height;
  if aMinHeight>0 then
    if Result < aMinHeight then
      Result := aMinHeight;
  if aMaxHeight>0 then
    if Result > aMaxHeight then
      Result := aMaxHeight;
end;

Параметры

aText - текст, который там отображен,

aWidth - ширина текстового объекта,

aMinHeight - минимально возможная высота (0 - если не нужно ограничение)

aMaxHeight - максимально возможная высота (0- если не нужно ограничение)

aFont - шрифт, используемый объектом

 

Сразу скажу, чтоб не говорили, что плагиатор, да основная часть и идея функции взята с этого форума.

P.S.Прибавил 4 пикселя, для того, чтобы рамка поместилась

 

Ссылка на комментарий
  • 0

то же сам писал но не устроило скорость работы а листвью пока устраивает

Скорость будет говно если итемы будут контролами, если вручную просто отрисовывать свои итемы на канве, то скорость такая же как и у ListView, ибо он работает по такой же схеме.

Ссылка на комментарий
  • 0

я имел ввиду что скорость не сравнить с VCL гридом. а если скорость не выше то зачем городить огород? я VCLный DBGrid переделал под FMX. очень я бы сказал печальное зрелище было листать туда сюда страницы с текстом по сравнению в VCL. VCL использует WinAPI и там все летает. FMX использует DirectX и все тормозит. Если бы сделали обертку к WinAPI как к DirectX тогда бы FMX летать начал под виндой. 

Ссылка на комментарий
  • 0

Я делал для мобилок (ФМ). Скорость работы идеальная, ни единого притормаживания. На лету определяет какие итемы сейчас должны быть видны в контроле и подгружает картинки только для этих итемов. Пробовал запилить 1000 итемов с картинками внутри каждого итема, 0 лагов. Ну собственно и лагать не от чего, картинок загружено в память минимум, отрисовка всегда идет только видимых итемов. Хотя конечно и в ListView можно сделать тоже самое, просто устал постоянно ворошить исходники этого монстра (TListView) для того чтобы добавлять/менять свой функционал.

Ссылка на комментарий
  • 0

размер экрана 2048х1536, сколько памяти уйдет на хранение картинок для базы в 2-3000 записей по 20-30 полей в каждой? :) пробовал я это делать на дбгриде. но как увидел что памяти жрет сие решение не меряно и при большой количестве записей может вообще выкинуть из-за недостатка оной, особенно на устройствах с 512 памятью, то отказался от этого. слегка подлагивает да и хрен с ним за то памяти не жрет. 

Ссылка на комментарий
  • 0

То ли я вас не понял то ли вы меня. Я сделал так, что в памяти загружены только несколько картинок одновременно, а точнее ровно столько сколько видно итемов. Допустим высота контрола 1000, Высота итема 100. Так вот в памяти всегда загружено именно 11 картинок как бы вы не скролили вниз или вверх количество кушаемой памяти практически не меняется. Если итем не виден то картинка для него выгружается из памяти вообще. Ограничение такого подхода только в том что картинки для этого контрола должны храниться локально в файлах на устройстве.

Ссылка на комментарий
  • 0

То ли я вас не понял то ли вы меня. Я сделал так, что в памяти загружены только несколько картинок одновременно, а точнее ровно столько сколько видно итемов. Допустим высота контрола 1000, Высота итема 100. Так вот в памяти всегда загружено именно 11 картинок как бы вы не скролили вниз или вверх количество кушаемой памяти практически не меняется. Если итем не виден то картинка для него выгружается из памяти вообще. Ограничение такого подхода только в том что картинки для этого контрола должны храниться локально в файлах на устройстве.

так, а Вы используете ListBox  что ли?

Ссылка на комментарий
  • 0

то есть создается для каждого итема картинка, сохраняется типа во внутренюю память а потом считывается от туда при появлении этого итема? и без лагов? я про разрешение не зря написал. при таком разрешении при ширине в 2048 подгрузка должна занимать время да и места на диске немеряно. теоретически конечно. да и как отслеживается появление ненужных лишних картинок? ведь по идее если данные будут часто меняться надо ненужные картинки удалять а новые сохранять. или при запуске программы чистить весь кэш картинок и заново все пересоздавать. это хорошо для полной статики но для динамики хз. 

Ссылка на комментарий
  • 0

Картинки изначально уже лежат на устройстве. У каждого итема есть поле в котором хранится путь к файлу картинки. При скроле этого контрола каждый раз высчитывается какие итемы сейчас должны быть в области видимости. Дальше идет проверка, загружена ли в память уже картинка для каждого видимого итема ну и соответственно загружается или ничего не делается. Дальше вызывается Paint и в нем начинается рисование итемов контрола. Так что да картинки для итемов подгружаются и выгружаются на лету во время скрола. На андроидах не пробовал, пробовал на своем Iphone 5s. Ни малейшего лага нет, загружаются картинки моментально. Насчет размеров картинок. Не знаю как вы используете списки, но у меня задача отображать итемы с несколькими строками и слева картинка у каждого, в общем как и у стандартного ListViewItem'а. Высота итема у меня 60. Загружаются в итемы не какие-нибудь гиганты непонятных разрешений, а миниатюры картинок размером чуть большим чем высота итемов (90) для того чтобы было приемлимое качество картинки. Можете не верить, ваше право, но при скроле нет ни малейших дерганий или тем более зависаний (1000 итемов), скролится все плавно, в общем также как и ListView без картинок. По сути многое я подсмотрел у ListView, принципиальная разница лишь в том что если у контрола 1к итемов, то они не загружаются все в память. Да и шансов на то что приложение не вылетит при 1000 итемах и загруженных к ним картинках практически нет.

Ссылка на комментарий
  • 0

Картинки изначально уже лежат на устройстве. У каждого итема есть поле в котором хранится путь к файлу картинки. При скроле этого контрола каждый раз высчитывается какие итемы сейчас должны быть в области видимости. Дальше идет проверка, загружена ли в память уже картинка для каждого видимого итема ну и соответственно загружается или ничего не делается. Дальше вызывается Paint и в нем начинается рисование итемов контрола. Так что да картинки для итемов подгружаются и выгружаются на лету во время скрола. На андроидах не пробовал, пробовал на своем Iphone 5s. Ни малейшего лага нет, загружаются картинки моментально. Насчет размеров картинок. Не знаю как вы используете списки, но у меня задача отображать итемы с несколькими строками и слева картинка у каждого, в общем как и у стандартного ListViewItem'а. Высота итема у меня 60. Загружаются в итемы не какие-нибудь гиганты непонятных разрешений, а миниатюры картинок размером чуть большим чем высота итемов (90) для того чтобы было приемлимое качество картинки. Можете не верить, ваше право, но при скроле нет ни малейших дерганий или тем более зависаний (1000 итемов), скролится все плавно, в общем также как и ListView без картинок. По сути многое я подсмотрел у ListView, принципиальная разница лишь в том что если у контрола 1к итемов, то они не загружаются все в память. Да и шансов на то что приложение не вылетит при 1000 итемах и загруженных к ним картинках практически нет.

Очень интересно, а можно набраться наглости и попросить какую-нить демку Вашего решения. Очень нужно такое же.

wamaco@mail.ru

спасибо!

Ссылка на комментарий
  • 0

а пробовал на ipad который ретина запускать? или на 6 огрызке у которого разрешение побольше? я так понимаю картинки сделаны под один телефон с одним разрешением? 

 

я не к тому что ты типа что то там не правильно сделал. просто интересно. я тоже хотел пойти таким путем. но на гриде с кучей ячеек и строк. там каждая ячейка которая должна была прорисоваться преобразовывалась в картинку а потом показывались только картинки. стало на компе очень плавно скролиться даже когда грид разворачивал на весь экран. НО памяти стала программа отъедать под 400 - 500 метров. на андроиде с начало показывало нормально, первый экран но как память при скроле забилась, стали на картинках артефакты появляться всякие в виде цветных полос и точек. А так как грид был не статический то просто картинками с диска там не обойдешься ибо в него нужно было вбивать пользователям свои данные. как то так. посему данную задумку закопал :)

Ссылка на комментарий
  • 0

На ipad не пробовал. Картинки не сделаны под какойто телефон, изначально они на телефоне лежат с разрешением 1024х768, просто загружаются в битмап он ине loadfromfile, а loatThumbnail, соответственно и памяти кушает в 10 раз меньше. Далее. Есть по-моему огромная разница замостить картинками целый ДБгрид на всем экране или по одной картинке в каждый элемент списка, как минимум разница во столько раз, сколько колонок в ДБГриде. Насчет поедаемой памяти вообще вас не понял. Контрол держит в памяти только столько картинок, сколько итемов видно, а это всегда величина постоянная и небольшая с учетом загрузки миниатюр, а не гигантов реальных размеров. ДБГрид и список - огромная разница в этой реализации ибо у списка в момент скрола если появляется новый элемент в области видимости, то загрузить нужно всего 1 картинку и выгрузить 1, а в гриде много картинок одновременно надо подгружать удалять. Ну и критиковать проще всего. У вас есть решение которое бы позволило иметь огромные списки в тысячу и более элементов с картинками и не вызывало out of memory? Проверю это решение на IPad2, если уж на этом говне будет нормально, то о чем еще говорить... А цели сделать этот список чтобы он хорошо работал у всех бомжей у меня нет, спасибо, хватил уже истории когда всем нужна была поддержка идиотского IE6. Думаю не стоит разработчикам 2 раза на 1 грабли наступать.

Ссылка на комментарий
  • 0

память забивается потому картинки хранятся именно в памяти а не на диске. почему? есть у тебя грид. в нем надо отобразить и список клиентов, и информацию о клиентах и список товара, и информацию о товаре, и документы и информацию о документах. на все это картинок не наделаешь и на диск не на сохраняешь ибо займет это место немеряно. а учитывая что в одну строчку в гриде не всегда может попасть одна и та же информация вообще не целесообразно. 

 

можно конечно и в динамике создавать картинки и убивать их по мере пролистывания списка, но при быстром скроле не по одной строчке тормоза должны быть еще больше чем без картинок, ибо двойная работа получается, 1 шаг тут же создается картинка и 2 шаг она прорисовывается на канве, и практически тут же удаляется так как итем улетел за область видимости. 

Ссылка на комментарий
  • 0

Ну в общем-то стало понятно что мы до сих пор о разном. Судя по вашему сообщению,вы думаете, что у меня все итемы это какие-то мифические картинки. У меня точно такие же итемы как и в ListView. Точно также в них есть текст и картинка слева. И "список клиентов, и информацию о клиентах и список товара, и информацию о товаре, и документы и информацию о документах" - это все текст. Картинкой в итеме является только картинка, которая слева. К примеру список людей: слева маленькая фотка сотрудника, а справа (ФИО, возраст, цвет трусов) это текст, а не картинка.

Изменено пользователем xenon54
Ссылка на комментарий
  • 0
  • Модераторы

 

Копался, копался так ничего и не получилось, в итоге сделал как предложил ruslan (пост 4) но со своими доработками, если кому интересно

на создание объекта и на событие OnUpdatingObjects (на TListView) сделал

   aItem.Height := Round(CalculateTextHeight(aItem.Text, aItem.Objects.TextObject.Width, 36, 130, aItem.Objects.TextObject.Font))+4;
aItem - TListViewItem - элемент списка из TListView
 
сама функция вот
function CalculateTextHeight(aText: String; aWidth: Single; aMinHeight: Single = 0; aMaxHeight: Integer = 0; aFont: TFont) : Single;
begin
  FTextLayout.BeginUpdate;
  try
    FTextLayout.Text := aText;
    FTextLayout.MaxSize := TPointF.Create(aWidth, 1000);
    FTextLayout.WordWrap := True;
    FTextLayout.Font.Assign(aFont);
    FTextLayout.HorizontalAlign := FMX.Types.TTextAlign.Leading;
    FTextLayout.VerticalAlign := FMX.Types.TTextAlign.Leading;
  finally
    FTextLayout.EndUpdate;
  end;
  Result := FTextLayout.Height;
  if aMinHeight>0 then
    if Result < aMinHeight then
      Result := aMinHeight;
  if aMaxHeight>0 then
    if Result > aMaxHeight then
      Result := aMaxHeight;
end;

Параметры

aText - текст, который там отображен,

aWidth - ширина текстового объекта,

aMinHeight - минимально возможная высота (0 - если не нужно ограничение)

aMaxHeight - максимально возможная высота (0- если не нужно ограничение)

aFont - шрифт, используемый объектом

 

Сразу скажу, чтоб не говорили, что плагиатор, да основная часть и идея функции взята с этого форума.

P.S.Прибавил 4 пикселя, для того, чтобы рамка поместилась

 

 

FTextLayout - это что за компонент?

Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...