DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: webb123
今日帖子: 13
在线用户: 27
导航: 论坛 -> 移动应用开发 斑竹:flyers,iamdream  
作者:
男 janker (janker) ★☆☆☆☆ -
盒子活跃会员
2022/9/19 19:18:26
标题:
请问如图的效果FMX如何实现,手机APP 浏览:2504
加入我的收藏
楼主: 如图,是手机APP,原图是微信小程序的,现在想用FMX实现:
(贴图见附件)
左边是商品类别按钮,右边是商品列表,是个垂直滚动列表,带有GroupHeaderItem(商品类别名称),点击类别按钮,列表就滚动显示此类商品,GroupHeaderItem就正好显示在列表框的顶部。
本来想直接用TabControl实现,客户说还是按原来的效果实现。
试了下,界面颜色效果什么的都好实现,左边用Layout+TSpeedButton就可以,右边用TListBox,但是TListBo.ScrollItem()方法只能把定位的Item显示在列表框的底部,这个倒是可以通过获取ListBox的ScrllBar的值来使定位Item滚动到顶部。但是,有个问题无法解决,就是右边商品滚动的时候,左边的按钮也能跟随变化,就和点击此按钮的效果一样,
类似PDF那样,内容页面滚动时,左边的标签页(目录)也能跟随变化,这个效果不知道从何下手。
或者FMX有其它控件可以达到此效果的吗?
好像网页也有此类效果的,CSS实现这样的效果比较容易?(Delphi的帮助就有这样的效果....)
此帖子包含附件:
JPEG 图像
大小:92.2K
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2022/9/19 21:20:40
1楼: 楼上,你这个用主从表。一个是大类表,一个是类里面的产品表。

两个并排的 ListView,分别用 LvieBindings 绑定两个表。搞定。

实在你搞不来 ListView,你就用 ListBox,自己用代码,创建 ListBox 里面的每个 ListBoxItem,也能搞定。
----------------------------------------------
-
作者:
男 k3man (嗯哼) ★☆☆☆☆ -
普通会员
2022/9/19 21:39:13
2楼: 界面好搞定,楼主要的是当利口酒推动到主显时,是否要关联左侧按钮到利口酒为激活状态?
----------------------------------------------
-
作者:
男 janker (janker) ★☆☆☆☆ -
盒子活跃会员
2022/9/19 21:56:09
3楼: 2楼说的就是我的意思。。。
计算ScrollBar.Value的值,某个ITEM滚动到列表框的顶部时,就是触发的时候....
----------------------------------------------
-
作者:
男 janker (janker) ★☆☆☆☆ -
盒子活跃会员
2022/9/19 22:02:36
4楼: 左边的按钮点击,可以实现某个ITEM滚动到列表框顶部。
右边列表框主动滚动时,当个特定ITEM滚动到列表框顶部时,左边某个按钮聚焦,这个还没实现......
----------------------------------------------
-
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2022/9/19 22:34:29
5楼: I think that this behaviour DONT USE "master-detail" technic! NO NO NO

I think that is "better" use "events" of each ListView and find the records in each table, just like this:

implementation

{$R *.fmx}

var
  UseListViewChangeEvent: boolean = false;

procedure TForm1.FormCreate(Sender: TObject);
var
  LVchildren: TControl;
begin
  // not Scroll visible, BUT working!!!
  for LVchildren in ListView1.Controls do
    if LVchildren is TScrollBar then
      LVchildren.Width := 0;
  //
  for LVchildren in ListView2.Controls do
    if LVchildren is TScrollBar then
      LVchildren.Width := 0;
  //
  // no Accessory visible...
  ListView1.ItemAppearanceObjects.ItemObjects.Accessory.Visible := false;
  ListView2.ItemAppearanceObjects.ItemObjects.Accessory.Visible := false;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  UseListViewChangeEvent := true; // ok... you can use this event now!
end;

procedure TForm1.ListView1Change(Sender: TObject);
begin
  if not UseListViewChangeEvent then
    exit;
  //
  BindSourceDB2.DataSet.Locate('CUST_NO', BindSourceDB1.DataSet.FieldByName('CUST_NO').AsInteger, []);
end;

procedure TForm1.ListView2Change(Sender: TObject);
begin
  if not UseListViewChangeEvent then
    exit;
  //
  BindSourceDB1.DataSet.Locate('CUST_NO', BindSourceDB2.DataSet.FieldByName('CUST_NO').AsInteger, []);
end;

end.
此帖子包含附件:
PNG 图像
大小:83.5K
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2022/9/19 22:37:19
6楼: CUSTOMER TABLE =>  SELECT * FROM CUSTOMER
SALES TABLE    =>  SELECT * FROM SALES

screenshot
此帖子包含附件:
PNG 图像
大小:43.3K
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2022/9/19 22:45:36
7楼: another tip:

-- You can use "TStyleBook" to edit the ListView style for changes the colors, and others effects necessary!!!

Ex.:  Frame COLOR === Background COLOR to hide separate-line between records!
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2022/9/19 23:01:11
8楼: 2 楼说的问题也很简单。

你用两个表,也就是两个 DataSet ,对 ListView 做 LiveBInding。

然后,DataSet.AfterScroll 事件里面,从表滚动到底,就让主表往下滚动。

搞定。

不要在界面上想办法。现在的思路,应该是在数据上想办法,界面最好什么都不要做。这个才是现在所谓的 MODEL - VIEW 的模式嘛。
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2022/9/19 23:03:00
9楼: 其实 Delphi 传统的数据库的 DataSet - DataSource - DBGrid 的方式,也同样是操作 DataSet 而不是操作 DBGrid 的。想要 DBGrid 里面的光标滚动,同样是操作 DataSet 的。
----------------------------------------------
-
作者:
男 janker (janker) ★☆☆☆☆ -
盒子活跃会员
2022/9/20 0:55:43
10楼: 我这个也没涉及数据库,服务端是别人写的,好像是PHP,我是get JSON数据。
这个我想也不涉及到lvieBanding,一次如果只显示一个类别的商品,我想用TabControl分页显示更简单。
emailx45 和pcplayer 说的,没明白怎么实现我要的效果。。。。

右边商品列表不是一次性加载的(这样慢,试了不行,太慢了,不是局域网,不是云端,是内网映射的服务端)
比如初始只显示“店长推荐”,都不用滚动,然后用户点了“饮料类别”,这时列表增加饮料类别商品,是增加,不是清空显示。然后又点了“威士忌”,这时是要在列表插入“威士忌”类别的商品,总之商品列表顺序和类别顺序要一样。如果全部类别点击一遍,全部商品才显示。。。
所以这个用主从表和绑定应当实现不了。。。
不过谢谢你们啦,我描述的不清楚。。。。
----------------------------------------------
-
作者:
男 janker (janker) ★☆☆☆☆ -
盒子活跃会员
2022/9/20 1:21:05
11楼: 点击商品类别,让商品列表可以按要求滚动,这个可以做到,很简单的:
ListBox的ScrollBar是protected的,但是可以在Form是声明:
TListBox = class(FMX.ListBox.TListBox);
就可以访问private和protected

listbox1.ScrollItem(listboxitemFirst); 如果是第一项,这样就可以让listboxitem1显示在列表框的顶部;
listbox1.ScrollItem(listboxitemLast); 最后一项Item显示在列表框的底部。

listbox1.ScrollItem(listboxitemXXX);
listbox1.ScrollBar.Value:=listbox1.ScrollBar.Value+listbox1.ClientHeight;
这样,可以让listboxitemXXX显示在列表框的顶部。
(ScrollItem的源码,是根据Content(这个是全部的列表项)和ContengLayout(这个是当前显示的)的相对大小来决定ScrollBar.Value)

现在要解决的是:
用户滚动了列表框,怎么相应地使类别按钮点亮。。。。
比如滚动列表框,当“利口酒”这个Item滚动到列表框顶部的时候,左边的“利口酒”按钮点亮。
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2022/9/20 1:37:56
11楼: JSON 数据你是可以导入 FdMemTable 的,这样就可以操作 DataSet 了。

可以操作 DataSet,然后再 LiveBinding 那就是界面和数据可以互动了。

至于你说数据是增加,那每次从服务器获得数据后,追加到 FdMemTable 里面去就好了。

我刚才测试了一下,FireMonkey 的 ListView 在走到最后一条后,触发的 DataSet 的 afterScroll 里面,不会出现 EOF,这个在 DBGrid 里面是可以的。

因此,就不搞主从表,反正一直往下走,倒过来,产品表有 AfterScroll 事件,去 Locat 产品类别表。一样实现。

至于不是一次加载的问题,并不影响主从表的问题。

TabControl 的问题,也不是你要的效果啊。TabControl 只是几个界面用 Tab 来切换。你的图片是左边一个列表,右边一个列表。这个和 TabControl 有什么关系?

如果一次只显示一个类别的商品,最简单的做法,要么用主从表,要么用过滤。

但如果只显示一个类别的商品,你要考虑产品列表走到结尾的时候,怎么办?如果你能够检测用户手势的上滑动作,然后根据这个上滑动作,自动把主表切换到下一条记录,也是可以的。这样的话,用主从表,或者用过滤,都是可以的。
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2022/9/20 2:04:00
12楼: 我测试了一下,如果用 LiveBinding,也可以把 TabControl 的 TabIndex 绑定到 DataSet 的整数字段上,当 DataSet 的游标走动,TAB 自动跟随。

问题是,FireMonkey 的 TabControl 是真正的页。除非你每个页。

当然,你也可以每个页,都放一个 ListView 来显示从表的记录。

不过,我还没找到让 FireMonkey 的 TabControl 的 Tab 标签朝向左边或者右边的办法,它只能上下,如果我让它旋转 90 度,它就无法正确的 Align 为 Left 了。
----------------------------------------------
-
作者:
男 janker (janker) ★☆☆☆☆ -
盒子活跃会员
2022/9/20 2:15:48
12楼: pcplayer (pcplayer):
谢谢你,用内存表来处理数据,我没往这方面想啊。这个小程序只是个客户端,只是显示操作用的,所以不用缓存什么数据。
我用的是ListBox,简单。设计好ListBoxItem的Style就好,操作比ListView简单。
ListBox滚动触发DataSet的AfterScroll事件?是Item过列表框的底部时触发吗?这个没试过。。。
如果是单类别显示,用TabControl和TListBox都简单。用TabControl就不显示Tab呗,左边的商品类别按钮就当是Tab用了。。这个窗体是个临时窗体,不关闭的时候,是不用刷新数据的,查询一次就好。可惜用户不同意,给微信小程序的参考界面给毒了。。。
(实际是微信小程序是不支持列表滚动点亮类别按钮的,是用户提出的意见)

实际是用户用微信小程序用的好好的,现在要改动,只是因为微信不支持支付宝!!!
所以我们才有活干。。。。。
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2022/9/20 2:37:33
13楼: 我平常用买菜小程序。我看好几家的买菜小程序,都是网页。

那么,你用 Delphi 做,你的优势在哪里?

优势就是你可以缓存数据啊。你第一次从服务器拉数据过来,写入本地的 SQLite,以后,每次打开 APP,直接本地加载商品数据,快啊。尤其网 - 络慢半天刷新不出来的时候。

网 - 络慢的时候,你的用户体验就比网页版好了。这个是 Delphi 的优势!

当然,如果商品数据变化了,你的程序要重新拉数据过来覆盖掉原来的数据。

用 ListView 最大的好处是 LiveBinding,没几行代码,你要的功能就有了。我三分钟就做出来了。其中 2 分钟是花在给 FdMemTable 手动填数据上面。
----------------------------------------------
-
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2022/9/20 8:18:43
14楼: try my changes....

NOTE: with automatic "Scrolling...." on second ListView!!!
//----------//
type
  TForm1 = class(TForm)
    fdCategory: TFDMemTable;
    fdCategoryID: TIntegerField;
    fdCategoryCategoryName: TStringField;
    fdProduct: TFDMemTable;
    fdProductID: TIntegerField;
    fdProductID_Category: TIntegerField;
    fdProductProductName: TStringField;
    fdProductProductPrice: TCurrencyField;
    Layout1: TLayout;
    ListView1: TListView;
    ListView2: TListView;
    procedure ListView1Change(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    procedure LoadDataOnListView;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

var
  YouCanUseListViewChangeEvent: boolean = false;

procedure TForm1.FormCreate(Sender: TObject);
begin
  fdCategory.Close;
  fdCategory.IndexFieldNames := 'CategoryName'; // for sort it...
  //
  fdProduct.Close;
  fdProduct.IndexFieldNames := 'ProductName'; // for sort it...
  //
  fdCategory.Open;
  fdProduct.Open;
  //
  FormatSettings.CurrencyString   := 'R$';
  FormatSettings.CurrencyDecimals := 2;
  //
  LoadDataOnListView;
end;

procedure TForm1.LoadDataOnListView; // you can to do another way...
var
  LVItem: TListViewItem;
begin
  ListView1.Items.Clear;
  //
  fdCategory.First;
  //
  // creating a ListView2 "Header + sub-items...."
  //
  while not fdCategory.Eof do
    begin
      fdProduct.Filtered := false;
      fdProduct.Filter   := 'ID_Category=' + fdCategoryID.AsString;
      fdProduct.Filtered := true;
      //
      fdProduct.First;
      //
      if not fdProduct.Eof then
        begin
          LVItem         := ListView2.Items.Add;
          LVItem.Text    := fdCategoryCategoryName.AsString;
          LVItem.Purpose := TListItemPurpose.Header;
          //
          while not fdProduct.Eof do
          begin
          LVItem        := ListView2.Items.Add;
          LVItem.Text   := fdProductProductName.AsString;
          LVItem.Detail := FloatToStrF(fdProductProductPrice.AsCurrency, tfloatformat.ffCurrency, 15, 2);
          //
          fdProduct.Next;
          end;
        end;
      //
      fdCategory.Next;
    end;
  //
  fdProduct.Filtered := false;
  fdProduct.Filter   := '';
  fdProduct.First;
  //
  fdCategory.First;
  //
  while not fdCategory.Eof do
    begin
      LVItem      := ListView1.Items.Add;
      LVItem.Text := fdCategoryCategoryName.AsString;
      LVItem.Tag  := fdCategoryID.AsInteger;
      //
      fdCategory.Next;
    end;
  //
  fdCategory.First;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  YouCanUseListViewChangeEvent := true; // ... to "OnChange" (ListView1) job!
end;

[b] ---> JUST THIS PROCEDURE DO ALL
procedure TForm1.ListView1Change(Sender: TObject);
begin
  if not YouCanUseListViewChangeEvent then
    exit;
  //
  for var i: integer := 0 to (ListView2.ItemCount - 1) do
    if (ListView2.Items[i].Purpose = TListItemPurpose.Header) and { }
      (ListView2.Items[i].Text = ListView1.Items[ListView1.ItemIndex].Text) then
      begin
        ListView2.ItemIndex := i;       // Header...
        ListView2.ItemIndex := (i + 1); // Item...
        //
        break;
      end;
end;
[/B]

end.
//**********//
此帖子包含附件:
PNG 图像
大小:74.3K
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2022/9/20 8:20:41
15楼: using "SQL" (like FDQuery) is better than my "WHILE Dataset.EOF do ...." procedure!
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2022/9/20 8:48:29
16楼: ...
       while not fdProduct.Eof do
       begin
          LVItem        := ListView2.Items.Add;
          LVItem.Tag    := fdProductID_Category.AsInteger;  <-----
...
          //
          fdProduct.Next;
       end;

.....


procedure TForm1.ListView2Change(Sender: TObject);
begin
  if not YouCanUseListViewChangeEvent then
    exit;
  //
  for var i: integer := 0 to (ListView1.ItemCount - 1) do
    if (ListView1.Items[i].Tag = ListView2.Items[ListView2.ItemIndex].Tag) then
      begin
        ListView1.ItemIndex := i;  <---- select in ListView1
        //
        break;
      end;
end;
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2022/9/20 8:59:03
17楼: 我把例子代码做出来了,使用数据绑定,效果没问题:

https://blog.csdn.net/pcplayer/article/details/126945466
----------------------------------------------
-
作者:
男 janker (janker) ★☆☆☆☆ -
盒子活跃会员
2022/9/20 14:36:39
18楼: 谢谢俩位的热心解答。
listview有个scrollvewpos属性,这个真不知道,一般做简单的ITEM我都是用listbox来做的,很少用listview。(我记得原来版本的listview里面的各个元素赋值好麻烦的,好像现在改进了?),有这个scrollvewpos属性,可以控制某个特定ITEM 过listview顶部的时候,触发事件。。。
这里的Item里面包含按钮,颜色块和文字等实时变动的因素,不是只是简单的取自数据库的数据,所以不用LiveBinding,因为Item里面元素的不固定,还是要代码控制的,所以不如直接全部用代码。
另外,说明下,原来是有本地SQLITE缓存的(是为了界面刷新速度),后来发现意义不大,因为每次创建这个窗体,都得从服务端取数据(甚至根据客户情况,点击分类按钮或列表框滚动的时候,都得从服务端拉数据。。。),用了SQLITE更麻烦。

我改为ListView试试。。。谢谢
----------------------------------------------
-
作者:
男 janker (janker) ★☆☆☆☆ -
盒子活跃会员
2022/9/20 16:36:06
19楼: 哎呀呀,笨啊。。。。
TListBox有个简单的方法:
ItemByPoint()
在OnViewportPositionChange()里面检测,
不能在OnVScrollChange()里,因为客户区滚动的时候,不触发

ListViewItem的Style搞不定,太复杂了,用TListBox....
----------------------------------------------
-
作者:
男 k3man (嗯哼) ★☆☆☆☆ -
普通会员
2022/9/20 21:47:07
20楼: 太复杂了,其实核心代码就两行。参阅附件!
此帖子包含附件:k3man_2022920214654.rar 大小:1.10M
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2022/9/20 23:48:22
21楼: 你如果仅仅是要知道是否有走到最底部,好自己写代码去点亮左侧的选项,还有个更基本的办法,就是做一个 Frame 作为一个条目,运行期根据数据条数创建 Fame 实例,摆进一个 ScrollBox 里面去,一律设置为 Top,顺序往上顶。

然后你检测:VertScrollBox1.ViewportPosition.Y

这个 ScrollBox 滚到最顶上,这个值是 0,滚到最底下,这个值等于:里面所有条目的高度 - ScrollBox 的 ClientHeight。因此,判断这个值,你就知道滚动到最底了。

这样,整个条目就是一个 Frame,里面你摆什么内容,怎么摆,都由你自己搞定。颜色什么的,自己贴图,不用去理会 Style。

那为啥还有 ListView 这样的东西呢?数据不多,自己动态创建一堆 Frame 摆上去挺好。数据多了,还是 ListView 运行得更快。
----------------------------------------------
-
作者:
男 janker (janker) ★☆☆☆☆ -
盒子活跃会员
2022/9/21 13:15:48
22楼: 因为我的Item里用不到默认Style里的元素,ListBoxItem的默认Style里的默认元素我全部删了,自己设计Item的Style,这个比ListViewItem方便(我不知道ListViewItem的默认Style默认元素全部删了会不会有问题),
ListBoxItem访问元素数据很方便的,StyleData[],ListViewItem通过FindObject()来访问元素。
我看官方的ListView的Demo,一个简单的效果,就要好多代码。。。
主要是我的Item里的界面的动态元素比较多,用ListBoxItem可以方便设计(主要是我以前的一个项目也是用ListBox来做的,图方便吧)
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2022/9/21 20:39:01
23楼: ListView 的每个条目的内容,可以在设计期,你自己设计。你在里面添加几个图片,添加几个文字元素,都没问题。设计期右键点 ListView 的菜单,里面有一个菜单项,进入设计模式,可以在 ListView 的条目上,随便添加东西。

我有一个 APP 就是用这种设计期修改它的内容的方式来做的。

当然,我也有用摆放 N 多个 Frame 到一个 ScrollBox 里面的方式做过 APP,那是因为条数很少,做 Frame 的好处是设计期你在里面摆什么更简单方便。
----------------------------------------------
-
作者:
男 k3man (嗯哼) ★☆☆☆☆ -
普通会员
2022/9/22 13:04:50
24楼: Listview 很强大,大数据量下,渲染速度比Listbox快,通过其扩展接口,可以做出你想要的任意布局。
此帖子包含附件:
PNG 图像
大小:129.9K
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2022/9/22 14:19:06
25楼: 24 楼:

ListView 我现在是在设计期设计它的外观和元素,然后再用 LiveBindings 去绑定数据让它自动显示。

调用接口的方式没玩过,能稍微提示一下怎么做吗?
----------------------------------------------
-
作者:
男 janker (janker) ★☆☆☆☆ -
盒子活跃会员
2022/9/22 22:11:48
26楼: 因为Item里面不是静态的元素,有Button,Edit等动态元素,所以即使绑定了静态部分的元素数据,动态的元素还是要代码控制。
如果是渲染速度差别大,看来要好好研究ListView,不能总图方便........
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2022/9/23 0:35:00
27楼: 楼上,ListView 的 Item 里面的元素,设计期可以任意增加。我是这样做的。

但既然设计期可以增加,那自然是可以用代码来增加的。只是我自己没这样做过,不知道如何做。你要去研究,肯定能搞清楚怎么做。
----------------------------------------------
-
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2022/9/23 8:59:15
28楼: implementation

{$R *.fmx}

procedure TForm1.Button1Click(Sender: TObject);
const
  ArrSizes: Array [0 .. 4] of integer = (80, 128, 25, 44, 68);
var
  LVI   : TListViewItem;
  LVIHgh: integer;
begin
  randomize;
  LVIHgh := ListView1.ItemAppearance.ItemHeight;
  //
  for var i: integer := 0 to 4 do
    begin
      LVI          := ListView1.Items.Add;
      LVI.Text          := 'LVI_' + ListView1.Items.Count.ToString;
      LVI.Data['Text1']      := 'Data...' + LVI.Text;
      LVI.Data['Accessory2'] := Image1.Bitmap;
      LVI.Height          := ArrSizes[i];
    end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  LIDraw  : TListItemDrawable;
  n       : integer;
  DataText: string;
begin
  Memo1.Text := '';
  //
  n := ListView1.ItemIndex;
  //
  if (n = -1) then
    exit;
  //
  LIDraw := nil;
  //
  for var i: integer := 0 to (ListView1.Items[n].Objects.Count - 1) do
    begin
      DataText := '';
      LIDraw   := ListView1.Items[n].Objects[i];
      if LIDraw.Data.IsObject then
        DataText := 'Data is a object'
      else
        DataText := LIDraw.Data.AsString;
      //
      Memo1.Lines.Add('Item=' + ListView1.Items[n].Text + ' Height=' + ListView1.Items[n].Height.ToString + ', ' + { }
        LIDraw.ToString { Name } + ' [Data=' + DataText + '] Height = ' + LIDraw.Height.ToString);
    end;
  //
  Memo1.Lines.Add('----------');
  //
  LIDraw := nil;
  LIDraw := ListView1.Items[n].Objects.FindDrawable('Text1');
  if not(LIDraw = nil) then
    Memo1.Lines.Add('Item=' + ListView1.Items[n].Text + ' Height=' + ListView1.Items[n].Height.ToString + ', ' + { }
      LIDraw.ToString { Name } + ' [Data=' + LIDraw.Data.AsString + '] Height = ' + LIDraw.Height.ToString);
end;

end.
此帖子包含附件:
PNG 图像
大小:53.0K
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2022/9/23 9:36:17
29楼: "Item" drawable into LVitem... new Height or another property....

  LIDraw := nil;
  LIDraw := ListView1.Items[n].Objects.FindDrawable('Text1');
  if not(LIDraw = nil) then
    LIDraw.Height := 100;
此帖子包含附件:
PNG 图像
大小:22.5K
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 k3man (嗯哼) ★☆☆☆☆ -
普通会员
2022/9/23 10:07:18
30楼: 现在Delphi能找到的现存资料确实不多,这里有一篇介绍接口单元的,你可以参考一下,
https://blog.csdn.net/yupor5/article/details/78609609
另外,通过自定义Listview外观,已经引用了扩展单元。进入单元仔细看看就基本有答案了。
28楼已经给出答案了。
----------------------------------------------
-
作者:
男 k3man (嗯哼) ★☆☆☆☆ -
普通会员
2022/9/23 10:15:23
31楼: 引入接口单元后
 Litem := ListView1.Items.Add;
    with Litem do
    begin
      Text := 'fdfd' + i.ToString;
      Data[TRatingsListItemAppearanceNames.Text2Name] := '售价:¥' + inttostr(i+1) + '.00'; //为txt1赋值
      Data[TRatingsListItemAppearanceNames.Text3Name] := '规格:个'; //txt2赋值
      Bitmap := Image1.Bitmap; //给图片赋值,可来自文件,也可来自内存流。
      Height := 80;
    end;
----------------------------------------------
-
作者:
男 k3man (嗯哼) ★☆☆☆☆ -
普通会员
2022/9/23 10:17:50
32楼: TRatingsListItemAppearanceNames.取决于你定义的什么样的外观,就会引用不同的类和成员属性。
----------------------------------------------
-
作者:
男 k3man (嗯哼) ★☆☆☆☆ -
普通会员
2022/9/23 10:19:23
33楼: 这个论坛手机上回复太痛苦了。体验不好。
----------------------------------------------
-
作者:
男 janker (janker) ★☆☆☆☆ -
盒子活跃会员
2022/9/23 13:04:18
34楼: 明白了,ListView控件本身就可以了做任意的布局,而不用设计Style。
ListBox要做这些东西,是要用Style来实现的。
ListBox通过StyleData[]来访问ITEM元素,ListView通过Data[]来访问元素。
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行242.1875毫秒 RSS