-
Постов
203 -
Зарегистрирован
-
Посещение
-
Победитель дней
1
Активность репутации
-
HyperZen получил реакцию от Brovin Yaroslav в Искаженное отображение Item
Вот после доработки Вашего проекта:
TestPr.rar
-
HyperZen отреагировална rareMax в Возвращаясь к вопросу о подсчете высоты текста TListView
От эмбр: http://community.embarcadero.com/blogs?view=entry&id=8542
procedure TVariableHeight.ListView1UpdateObjects(const Sender: TObject; const AItem: TListViewItem); var Drawable: TListItemText; SizeImg: TListItemImage; Text: string; AvailableWidth: Single; begin SizeImg := TListItemImage(AItem.View.FindDrawable('imgSize')); AvailableWidth := TListView(Sender).Width - TListView(Sender).ItemSpaces.Left - TListView(Sender).ItemSpaces.Right - SizeImg.Width; // Find the text drawable which is used to calcualte item size. // For dynamic appearance, use item name. // For classic appearances use TListViewItem.TObjectNames.Text // Drawable := TListItemText(AItem.View.FindDrawable(TListViewItem.TObjectNames.Text)); Drawable := TListItemText(AItem.View.FindDrawable('txtMain')); Text := Drawable.Text; // Randomize the font when updating for the first time if Drawable.TagFloat = 0 then begin Drawable.Font.Size := 1; // Ensure that default font sizes do not play against us Drawable.Font.Size := 10 + Random(4) * 4; Drawable.TagFloat := Drawable.Font.Size; if Text.Length < 100 then Drawable.Font.Style := [TFontStyle.fsBold]; end; // Calculate item height based on text in the drawable AItem.Height := GetTextHeight(Drawable, AvailableWidth, Text); Drawable.Height := AItem.Height; Drawable.Width := AvailableWidth; SizeImg.OwnsBitmap := False; SizeImg.Bitmap := GetDimensionBitmap(SizeImg.Width, AItem.Height); end;
-
HyperZen отреагировална Евгений Корепов в Возвращаясь к вопросу о подсчете высоты текста TListView
Полностью согласен. Ширину я устанавливаю в ListViewActionsUpdateObjects, и только после этого вызываю функцию.
-
HyperZen отреагировална krapotkin в Возвращаясь к вопросу о подсчете высоты текста TListView
у меня аналогичная функция содержит еще один важный момент
иногда ATextObject не имеет установленной ширины, т.е. значение по умолчанию=0!
тогда нужно либо всегда задавать ее при создании итема, либо передавать ее отдельным параметром
думаю над созданием наследников TDrawable которые кроме Offset имеют свойства Margins
OFF:
по идее, все это уже пройдено в HTML когда настала эпоха DIV-верстки. Мы пытаемся наощупь идти по тем же граблям
-
HyperZen отреагировална Евгений Корепов в Возвращаясь к вопросу о подсчете высоты текста TListView
Почитал, посмотрел все варианты и сделал работу над ошибками. Переделал свой, показанный выше, код. Проверил на Windows и Android, с стилем по умолчанию и другими стилями - работает безупречно. Так же не нуждается в подгонках типа "Height:= Round(t) + 30;".
Преимущество кода в том что на вход подаем ATextObject : TListItemText, т.е. можно легко использовать для вычисления Text или Detail.
function TFormMain.CalculateListItemObjectHeight(ATextObject : TListItemText) : Single; begin FTextLayout.BeginUpdate; try FTextLayout.Text:=ATextObject.Text; FTextLayout.MaxSize:=TPointF.Create(ATextObject.Width, TTextLayout.MaxLayoutSize.Y); FTextLayout.Font.Assign(ATextObject.Font); FTextLayout.WordWrap:=ATextObject.WordWrap; FTextLayout.Trimming:=ATextObject.Trimming; FTextLayout.HorizontalAlign:=ATextObject.TextAlign; FTextLayout.VerticalAlign:=ATextObject.TextVertAlign; finally FTextLayout.EndUpdate; end; Result:=FTextLayout.Height; end; Пример использования: у меня Text непредсказуемой длины, вверху ListItem, по всей ширине ListItem. Под Text располагаются слева Image, справа Detail. Текст Detail может быть от пары слов, до нескольких предложений
procedure TFormMain.ListViewActionsUpdateObjects(const Sender: TObject; const AItem: TListViewItem); Var AItemTextHeight, AItemDetailHeight, AItemImageHeight, AItemHeight : Single; AListView: TListView; begin AListView:=TListView(Sender); AItem.Objects.TextObject.Width:=AListView.Width - AListView.ItemSpaces.Left - // Вычисляем ширину Text AListView.ItemSpaces.Right - DefaultScrollBarWidth; AItemTextHeight:=CalculateListItemObjectHeight(AItem.Objects.TextObject); // Вычисляем высоту Text AItem.Objects.DetailObject.PlaceOffset.Y:=AItemTextHeight; // Устанавливаем смещение для Detail AItem.Objects.ImageObject.PlaceOffset.Y:=AItemTextHeight; // Устанавливаем смещение для Image AItemDetailHeight:=CalculateListItemObjectHeight(AItem.Objects.DetailObject); // Вычисляем высоту Text AItemImageHeight:=AItem.Objects.ImageObject.Height; AItem.Objects.DetailObject.Height:=AItemImageHeight; AItemHeight:=AItemTextHeight + Max(AItemDetailHeight, AItemImageHeight); // Вычисляем высоту всего Item AItem.Height:=Round(AItemHeight); end;
-
HyperZen отреагировална krapotkin в Ошибка InputBox...
в посте я привел точно рабочий код, проверил
uses FMX.DialogService
-
HyperZen отреагировална krapotkin в Ошибка InputBox...
на inputquery тоже пишет
[DCC Warning] Unit1.pas(44): W1000 Symbol 'InputQuery' is deprecated: 'Use FMX.DialogService methods'
-
HyperZen отреагировална krapotkin в Ошибка InputBox...
ну, для начала берлин пишет на доступном языке
[dcc32 Warning] Unit1.pas(44): W1000 Symbol 'InputBox' is deprecated: 'Use FMX.DialogService methods'
во вторых
конечно, налицо просто баг в FMX.Dialogs
но, если последовать совету компилятора то вот так
TDialogservice.InputQuery('Введите номер страницы', ['Ввод'], [''], procedure(const AResult: TModalResult; const AValues: array of string) begin case AResult of mrOk: begin e1.text:=avalues[0]; end; mrCancel: begin e1.text:='Отмена'; end; end; end ); отлично запустилось и сработало
-
HyperZen отреагировална Равиль Зарипов (ZuBy) в Ошибка InputBox...
InputQuery больше нет, смотрите AsyncInputDialog (или как то так, пока нет Берлина)
-
HyperZen отреагировална krapotkin в OnUpdateObjects OnUpdatingObjects в Берлине
я еще раз в этой теме приложу тестовый проект полностью рабочий под берлин с ресайзом
ListViewTestBerlin.7z
-
HyperZen отреагировална krapotkin в OnUpdateObjects OnUpdatingObjects в Берлине
Короче, нащупал линию поведения.
поместил код в OnUpdatingObjects и поставил AHandled:=True;
Срабатывает он теперь не при Items.Add, а при первом обращении к Item.Objects !
Будьте внимательны
P.S. ItemAppearance можно ставить любой
-
HyperZen отреагировална krapotkin в Как в DynamicAppearance режиме изменить текст в Footer и Header?
так я же говорю, там в Custom режиме просто создаются ListItemText c именем T,D,B и т.д.
в Dynamic смотрите на названия элементов, вы их сами создаете и они видны в окне Structure
тем не менее, для Header и Footer создается элемент с именем Text и все работает так же как и раньше
procedure TForm1.b1Click(Sender: TObject); begin lv1.Items[trunc(SpinBox1.Value)].Text := lv1.Items[trunc(SpinBox1.Value)].Text + '1'; end; -
HyperZen отреагировална krapotkin в Как в DynamicAppearance режиме изменить текст в Footer и Header?
procedure TForm1.b1Click(Sender: TObject); begin lbl1.Text:=lv1.Items[trunc(SpinBox1.Value)].Text; end; function TForm1.CreateItem(purpose: TListItemPurpose; const s:string): TListViewItem; begin Result := lv1.Items.Add; result.Purpose := purpose; result.text := s; end; procedure TForm1.FormCreate(Sender: TObject); begin CreateItem(TListItemPurpose.Header, 'Header 1'); CreateItem(TListItemPurpose.None, 'Item 1'); CreateItem(TListItemPurpose.None, 'Item 2'); CreateItem(TListItemPurpose.None, 'Item 3'); CreateItem(TListItemPurpose.Footer, 'Footer 1'); CreateItem(TListItemPurpose.Header, 'Header 2'); CreateItem(TListItemPurpose.None, 'Item 4'); CreateItem(TListItemPurpose.None, 'Item 5'); CreateItem(TListItemPurpose.Footer, 'Footer 3'); SpinBox1.Max := lv1.ItemCount-1; end;
-
HyperZen отреагировална krapotkin в Как в DynamicAppearance режиме изменить текст в Footer и Header?
футер и хедер это обычные итемы. на них лежат ListItemText, у тех есть Text
можно посмотреть код FindDrawable и найти способ как получить ссылку на них
но думаю, это обычный Item.TextObject
-
HyperZen отреагировална haword в Возвращаясь к вопросу о подсчете высоты текста TListView
function GetTextHeight(text: string; width: single; wordwrap: boolean; font: tfont; HAlign, VAlign: TTextAlign; Trimming: TTextTrimming): single; begin if FTextLyout = nil then FTextLyout := TTextLayoutManager.DefaultTextLayout.Create; FTextLyout.BeginUpdate; try // Инициализируем текстовый слой для корректного вычисления // размеров отображаемого текста FTextLyout.Text := text; FTextLyout.MaxSize := TPointF.Create(Width, 10000); FTextLyout.WordWrap := WordWrap; FTextLyout.Font := Font; FTextLyout.Trimming:= Trimming; FTextLyout.HorizontalAlign := HAlign; FTextLyout.VerticalAlign := VAlign; finally FTextLyout.EndUpdate; end; Result:=FTextLyout.Height; end; procedure TMainForm.GroupLVUpdateObjects(const Sender: TObject; const AItem: TListViewItem); var lvi: TListViewItem; t: Single; begin lvi:= TListView(Sender).Items[AItem.Index]; t:= GetTextHeight(lvi.Text, lvi.Objects.TextObject.Width, lvi.Objects.TextObject.WordWrap, lvi.Objects.TextObject.Font, TTExtAlign(lvi.Objects.TextObject.Align), TTExtAlign(lvi.Objects.TextObject.VertAlign) ); lvi.Height:= Round(t) + 30; end; у меня работает.
-
HyperZen получил реакцию от AngryOwl в Возвращаясь к вопросу о подсчете высоты текста TListView
Нашел-таки глюк/баг (не знаю как назвать правильно) - все работает корректно в Windows.
А вот что касается Android, то размер шрифта необходимо указывать вручную обязательно (даже если используете в ListViewItem неизменный размер шрифта), иначе время от времени наблюдаются артефакты в виде наложения текста, или уползания его на следующий Item.
Drawable := TListItemText(AItem.View.FindDrawable('txtMain')); Text := Drawable.Text; Drawable.Font.Size := ListView1.ItemAppearanceObjects.ItemObjects.Text.Font.Size; - эта строчка решила проблему.
-
HyperZen получил реакцию от #WAMACO в Возвращаясь к вопросу о подсчете высоты текста TListView
Ярослав! Все работает как надо, но при некоторых размерах шрифта (я подозреваю те размеры, про которые мы писали выше) все-таки вычисления некорректны - это касается платформы Windows.
На конкретном устройстве - все работает корректно с любым размером шрифтов!
-
HyperZen отреагировална Brovin Yaroslav в Возвращаясь к вопросу о подсчете высоты текста TListView
Сразу не могу вам ответить. Но могу предположить, что итем умеет отображать не только текст и имеет возможность различных вариантов расположения отображаемых данных. Именно по этому и нельзя заранее знать, какой способ вы будите использовать.
-
HyperZen отреагировална Евгений Корепов в Возвращаясь к вопросу о подсчете высоты текста TListView
У меня не заработал на XE8 к сожалению код. Но принцип тот же самый, разве что не совсем понятно что за "m"
// Get layout height Result := Round(Layout.Height); // Add one em to the height Layout.Text := 'm'; Result := Result + Round(Layout.Height);
Заметил странность, если установить размер шрифта отличный от стандартного, к примеру 11,99 или 12,01, то все начинает нормально работать, текст влазит. Но размер шрифта на экране в полтора раза меньше "стандартного". Не знаю какой стандартный, но точно не 12, больше похож на 14 или 15. Может из за этого и косяк? В недрах FMX расчет ведется с "стандартным" шрифтом 12, а на экране отрисовывается гораздо более крупным.
-
HyperZen отреагировална Brovin Yaroslav в Возвращаясь к вопросу о подсчете высоты текста TListView
Вот пример вычисления высоты итема. ListViewVariableHeightItems2.zip
Я этот пример показывал на лонче в питере.
-
HyperZen отреагировална Евгений Корепов в Возвращаясь к вопросу о подсчете высоты текста TListView
Подтверждаю что на андроиде этот код косячит, выдает высоту процентов на 10-15 меньше нужной. Осталось разобраться почему в других моих проектах все работает нормально. Может действительно из за большого текста с сплошными строками накапливается ошибка?
P.S. Заменил текст на кусок из книги, та же самая фигня, обрезает снизу.
-
HyperZen отреагировална Равиль Зарипов (ZuBy) в Возвращаясь к вопросу о подсчете высоты текста TListView
Решение может быть следующим: Этот текст без единого переноса, нужно добавить. Разделить текст на две части и посчитать их отдельно, после сложить и дать Itemу высоту
-
HyperZen получил реакцию от AngryOwl в Возвращаясь к вопросу о подсчете высоты текста TListView
Проблема решена! Всем спасибо!
type TAppearanceObjectsHelper = class helper for TAppearanceObjects function GetParentControl: TControl; property ParentControl: TControl read GetParentControl; end; function TAppearanceObjectsHelper.GetParentControl: TControl; begin Result := OwnerControl; end; Function GetParent(const AListItem: TListViewItem): TListView; begin result := AListItem.Objects.Appearance.ParentControl as TListView; end; И, соответственно, код уважаемого Евгения Корепова претерпевает незначительные изменения:
if (Sender is TListViewItem) then begin AListItem := Sender as TListViewItem; if (GetParent(AListItem) is TListView) then AListView:=GetParent(AListItem) as TListView Else Exit; ....
-
HyperZen отреагировална AngryOwl в Возвращаясь к вопросу о подсчете высоты текста TListView
Не помню как там TListView, но наверняка есть что-то типа TListView(_ваш_список_).VScrollBar.Width
Точно не буду утверждать, что так. Но получить текущую ширину скрола, думаю, можно. И обойтись без констант.
З.Ы. Кстати, они все-равно прописаны в константах, где-то в глобальных модулях...
-
HyperZen отреагировална Евгений Корепов в Возвращаясь к вопросу о подсчете высоты текста TListView
Так весь проект целиков и выложил. В форме только апперанс у ListView выставил в Custom. А куда дели Parent? Это важное свойство хранящее родителя. Может как то переименовали?
P.S. Вы можете AListView заменить за свой конкретный ListView, доступ через парент сделал для красоты и универсальности, если несколько ListView в проекте...