Перейти к содержанию
  • 2
krapotkin

Фреймворк для стандартного ListView

Вопросы

Всем привет!

После долгого творческого запоя я запилил альфу либы, которая позволяет юзать обычный, не-генномодифицированный ListView.
Данные подаются в виде модели данных, описание раскладки итема лежит в JSON.


Для работы пишется примитивный наследник класса-адаптера, который биндит данные модели на элементы из JSON. Я решил, что руками делать это дешевле чем через RTTI

{ TMyAdapter }

procedure TMyAdapter.SetupDrawableContent(const ADrawable: TListItemDrawable;
  const AData: TMyData);
begin
  if SameText( ADrawable.Name, 'text') then
  begin
    (ADrawable as TListItemText).Text := AData.Text;
  end
  else if SameText( ADrawable.Name, 'detail') then
  begin
    (ADrawable as TListItemText).Text := AData.Detail;
  end
  else if SameText( ADrawable.Name, 'balance') then
  begin
    (ADrawable as TListItemText).Text := FormatFloat('0.00', AData.Balance);
  end
  else if SameText( ADrawable.Name, 'reserved') then
  begin
    (ADrawable as TListItemText).Text := FormatFloat('0.00', AData.Reserved);
  end

end;

Главная хитрость и отличие от стандартного DynamicAppearance+LiveBinding - переменная высота итемов ListView и использование арифметики в описании раскладки.

Можно указать Detail.Y  = Text.Bottom + 5, ItemHeight = Detail.Bottom + 10, Detail.W = ItemWidth/2 - X

    {"Kind":"rect","Name":"BonusRect","Value":"",
      "Place":{"X":"itemwidth*3/4","Y":"Text.Y","W":"ItemWidth/4-5","H":"50"},
      "BorderColor":"#FF005500", "Color":"lime",
       "LineWidth":3},

    {"TextHAlign":2,"TextVAlign":1,"Kind":"text","Name":"Balance","Value":"",
      "Place":{"X":"BonusRect.x+5","Y":"Text.Y","W":"BonusRect.w-10","H":"50"},
      "WordWrap":true,
      "Color"	:"Black",
      "Font":{"Size":18,"Style":""}}
  ],
  "ItemHeight":"detail.bottom+10",

Это дает довольно гибкую систему. Не на все случаи жизни, но все, что нужно, можно после автоматической раскладки дополнительно приписать в OnUpdateObjects 

Код для работы примерно такой

procedure TForm1.FormCreate(Sender: TObject);
begin
  data:= TMyDataList.CreateFromFile(ExePath()+'data.json');  // загрузка в модель данных
  Adapter := TMyAdapter.Create(lvWallets, data.Items, ExePath()+'pattern.json');  // создание адаптера и загрузка шаблона
  Adapter.Pattern.SetupListView(lvWallets);  // задать отступы и разную мелочь
  Adapter.ResetView(); // здесь в цикле из модели данных создается нужное количество итемов ListView
end;

procedure TForm1.lvWalletsUpdatingObjects(const Sender: TObject;
  const AItem: TListViewItem; var AHandled: Boolean);
begin
  Adapter.SetupContent(AItem);  // загрузить текст, картинки и другое содержимое в элементы итема
  Adapter.Pattern.DoLayout(AItem);  // поправить раскладку в соответствии с содержимым элементов итема
end;

Для использования кроме стандартных - текст, картинка, кнопка - создано несколько дополнительных элементов итема - прямоугольник, круг, уголок, линия.

Отличие от ModernLV - , 
1) все происходит без правки системных файлов
2) пока нет колонок и других особых изысков.

На результат работы смотреть тут. Исходники пока не причесаны, будут чуть позже

 

ListViewFramework.7z

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

  • 0

ненавижу Deploy 

опять потерялся файл pattern.json, поэтому не создавался шаблон в целом, и парсер его тоже

приложил. у меня запустилось штатно. проверьте plz

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
48 минут назад, krapotkin сказал:

ненавижу Deploy 

опять потерялся файл pattern.json, поэтому не создавался шаблон в целом, и парсер его тоже

приложил. у меня запустилось штатно. проверьте plz

Предлагаю улучшение )

function TVK_LV_BaseAdapter<TDataItem>.AddPatternFromFile(
  const Filename: string): TVK_LVPattern;
begin
  if Not TFile.Exists(Filename) then
    raise Exception.Create('Template file not found');
  result := TVK_LVPattern.CreateFromFile(Filename);
  result.LV := LV;
  Patterns.Add(result);
end;

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Понял в чем дело - шаблоны лежат тут \vkrapotkin-vklistview-2389334d1383\Demo\Win32\Debug , а exe файл компилятор создает тут \vkrapotkin-vklistview-2389334d1383\Demo\

В настройках проекта, в Delphi Compiler, Output Direcrory = '', вместо '.\$(Platform)\$(Config)' по умолчанию.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

да. из-за перехода на новую версию IDE видимо при upgrade проекта у меня слетели настройки, которые были в .dproj 

я в реальном-то проекте JSON просто в константе храню, без файла, тут чисто иллюстрация возможности.

проверку добавлю. хотя теперь в CreateFromFile тоже есть Exception

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

еще один пример раскладки из реального проекта

image.png.24766623a986065242ab0be1d98bac7d.png

    {
      "Columns":[],
      "Variables": 
      [ 
        {"Y_UNIT":"12"}, 
        {"GAP":"8"}, 
        {"ITEM_H":"2*GAP+5*Y_UNIT"}, 
        {"IMG_H":"76"}, 
        {"IMG_W":"76"}, 
        {"STOCK_SIZE":"48"}, 
        {"PRICE_COLW":"53"} 
      ], 
      "Objects":
      [
        {"Name":"ID","Kind":"data"},
    ,
        {"Name":"img","Kind":"image",
         "Place":{"X":"0","Y":"0","W":"IMG_W","H":"IMG_H"},
        }
    ,
        {"Name":"Text","Kind":"text","TextHAlign":"leading","TextVAlign":"leading",
          "Place":{"X":"img.right","Y":"GAP","W":"itemwidth - IMG_W - GAP - 2*PRICE_COLW - GAP","H":"52"},
          "WordWrap":true, 
          "Color":"black",
          "Font":{"Size":12}
        }
    ,
        {"Name":"earlier","Kind":"text","TextHAlign":"leading","TextVAlign":"leading",
          "Place":{"X":"text.left","Y":"ITEM_H-2*GAP+2","W":"itemwidth - 2*PRICE_COLW","H":"Y_UNIT"},
          "WordWrap":false, 
          "Color":"green",
          "Font":{"Size":10}
        }
    ,
        {"Name":"price1","Kind":"text","TextHAlign":"trailing","TextVAlign":"trailing",
          "Place":{"X":"itemwidth-GAP-PRICE_COLW-W","Y":"GAP+2*Y_UNIT","W":"auto","H":"Y_UNIT*1.5", "priority":"WXYH"},
          "WordWrap":false, 
          "Color":"black",
          "Font":{"Size":15}
        }
    ,
        {"Name":"imgstrike","Kind":"image",
         "Place":{"X":"price1.x-5","Y":"price1.y","W":"price1.w+8","H":"price1.h"},
        }
    ,
        {"Name":"price2","Kind":"text","TextHAlign":"trailing","TextVAlign":"trailing",
          "Place":{"X":"price1.right-W","Y":"ITEM_H-GAP-Y_UNIT*1.5","W":"auto","H":"Y_UNIT*1.5", "priority":"WXYH"},
          "WordWrap":false, 
          "Color":"black",
          "Font":{"Size":15, "style":"bold"}
        }
    ,
        {"Name":"qty","Kind":"text","TextHAlign":"trailing","TextVAlign":"center",
          "Place":{"X":"itemwidth-PRICE_COLW-GAP","Y":"GAP","W":"PRICE_COLW","H":"2*Y_UNIT"},
          "WordWrap":false, 
          "Color":"black",
          "Font":{"Size":27, "style":"bold"}
        }
    ,
        {"Name":"imgstock","Kind":"image",
         "Place":{"X":"itemwidth-STOCK_SIZE-3","Y":"ITEM_H-STOCK_SIZE-4","W":"STOCK_SIZE","H":"STOCK_SIZE"},
        }
      ],
      "ItemHeight":"ITEM_H",
      "ItemSpaces":    {"X":"0","Y":"0","W":"0","H":""}, 
      "SideSpace":"0" 
    }

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Всем хай!

Использую этод код в нашем проекте (БОЛЬШОЕ спасибо за исходники!).

Описал шаблон pattern.json, разнам полям назначил разный размер шрифта.
Поля создаются, текст присваивается, но по непонятной для меня причине размер шрифта на правильный меняется только после возникновения события OnResize, причем меняется только для видимых в данный момент итемов.

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

Буду благодарен если кто-то сможет пояснить причину такого, чтобы пофиксить для будущих проектов!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

P.S.

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

(Видимо сказались приключения с деплоем)))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
5 часов назад, krapotkin сказал:

P.S.

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

(Видимо сказались приключения с деплоем)))

Или получать по http с сервера - тут вообще простор, можно дизайн списка менять на лету ))))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
2 часа назад, krapotkin сказал:

Безусловно)

Смотрю в секции Variables можно на лету вычисления делать. Через как арифметика считается (чтоб по исходникам не искать)? просто интересно.

И можно ли там использовать динамические параметры? Типа ширины ListView (или итема с учетом отступов)? Было бы вообще прикольно. Я обычно размер картинки как раз вычисляю динамически, в зависимости от ширины (типа 30% от ширины итема).

 

ЗЫ Присмотрелся, вижу itemwidth - видимо это как раз то что мне нужно.

Отредактировал Евгений Корепов

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

там из нетривиального есть itemwidth и remain = itemwidth - <элемент>.X

itemwidth считается с учетом отступов, т.е. значение чистое, правильное

вопрос про арифметику не совсем понял. там используется мой собственный парсер выражений

Для текста задается H = "Auto" - с автоматическим расчетом высоты

Отредактировал krapotkin

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
Опубликовано (изменено)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
2 часа назад, krapotkin сказал:

demo listview при запуске выдаёт ошибку при вызове Adapter.AddPatternFromFile(ExePath()+'pattern.json') в  XSuperObject.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

пока играл с материал-тенями, порушил маленько, не заметил
поправил демки, обновил репозитории

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

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

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

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

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

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


  • Похожий контент

    • От Dmitry Stolyarov
      Добрый день, подскажите, пжл, новичку...
      Есть ListView и ImageList с двумя картинками. В ListView Item добавлен Image. ListView заполняю из БД и пытаюсь вывести картинку в зависимости от значения поля БД, но в независимости от значения БД выводится одна и та же картинка.. Такое нельзя провернуть?
      procedure TForm6.ListViewNAMEUpdateObjects(const Sender: TObject;
        const AItem: TListViewItem);
        var IItem:TListItemImage;
      begin
       IItem:= aItem.Objects.FindDrawable('Image4') as TListItemImage;
      if (IItem<>nil) then
      with FDQuery1 do
       begin
       First;
       while not Eof do
        begin
         if FDQuery1FK_PRICE.AsInteger = 1 then begin
          IItem.ImageIndex:=1
         end else
            begin
               IItem.OwnsBitmap := True;
           IItem.ImageIndex:=0;
            end;
         Next;
        end;
       end;
      end;
       
    • От gresaggr
      Добрый день.
      Как под FMX в ListView сделать подчеркивание Detail в рантайме?
      Пытался делать так:
      LV.ItemAppearanceObjects.ItemObjects.Detail.Font.Style := [TFontStyle.fsUnderline]
      но не срабатывает.
      P.S. Возможно это применить не ко всем строкам, а только к некоторым?
    • От ice donkey
      Заполняю ListView в рантайме:
       
       
      LiveBindings не подходит, поэтому есть вопрос: а как задать фиксированный заголовок - чтобы в списке все Items, начинающиеся с буквы А были как бы объединены под одним заголовком А? Который  в свою очередь смещался бы только заголовком Б (с Items, которые на букву Б) и так далее.
       
      Пример:
       
    • От Sati
      Летом 2016 вопрос отображения объектов в ListView при создании Items уже обсуждался. Хочу ещё раз обсудить этот вопрос. А именно:
      Простой код 
      ListViewItem := ListView.Items.Add;
      ListViewItem.Objects.AccessoryObject.Visible := false; (или true, не важно)
      вторая строка не работает если до выполнения, ListView ни одного раза не отображался. Если же отображался хотя бы один раз - всё нормально.
      В предыдущих обсуждениях Krapotkin рекомендовал Resize и OnUpdateObjects. Если нет идей проще, то, конечно, воспользуюсь.  
       
    • От x11
      Если у элементов, идущих подряд одинаковый текст, то текст скрывается.
      Как это это отключить?
       
    • От x11
      Не понять, ни в справке найти, ни примеров, как получить текст из header.
      Как получить текст из какого-то элемента, есть пример:
      lvContacts.Items[li.Index].Objects.FindObjectT<TListItemText>('textTel').Text; а для заголовка ил подвала не нахожу примеров
    • От Erlan_krg
      Всем привет! Встретился с одной проблемой. Удаляю Item у ListView по нажатию кнопки, которая находится на ListViewItem
      procedure TfmAppointment.lvSelectedServicesButtonClick(const Sender: TObject;
        const AItem: TListItem; const AObject: TListItemSimpleControl);
      begin
          lvSelectedServices.BeginUpdate;
          if lvSelectedServices.ItemCount > 0 then
              lvSelectedServices.Items.Delete(AItem.Index);
          lvSelectedServices.EndUpdate;
      end;
      итем удаляется, но потом выскакивает ошибка Access violation at address 60BCB318 и то се бо се
       
      у ListView ItemAppearance выставлен на DynamicAppearance
      помимо родного объекта Text добавил еще один объект Text и кнопку
       
      но фишка в чем, если убрать дополнительный объект Text с ListWiewItem и удалить итем то ошибка не выскакивает)
       
      что за прикол?
    • От sinuke
      Доброго дня, форумчане
      Возникла проблема с тем, чтобы поменять местами два итема в ListView. ListView.Items не имеет метода Exchange, сами итемы не имеют метода Assign чтобы можно было один итем клонировать в другой / удалить / вставить
      У кого какие мысли? Как реализовать?
      Delphi 10.2 Tokyo
       
    • От x11
      Не могу понять, как записать текст в Footer text
       
       

    • От Mars M
      Загружаю большой список в ListView, время загрузки где то 5-7 секунд.
      Это много, по этому переделал что бы список загружался динамически, как к концу пролистывается, подгружаются новые данные.
      Все бы хорошо, но вот ScrollBar при загрузке новых данных меняет размер и позицию. 
      Это не очень нравиться
      Можно как то заранее настроить его размер под конечное число итемов?
      Или может как то по другому сделать.
  • Последние посетители   0 пользователей онлайн

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

×
×
  • Создать...