在 Firemonkey 中滚动后列表框项目发生变化

ListBox items change after doing scroll in Firemonkey

我正在 Firemonkey 中开发一个多设备应用程序,其中 Main class 有一个包含一些项目的 ListBox 组件。这些项目中的每一个都具有相同的自定义样式。

我的问题是当列表框中有太多项目时,我必须垂直滚动才能看到其余项目。在这种情况下,ListBox 有一个奇怪的行为,当我在向下滚动后向上滚动时,项目的组件(例如按钮)改变了他的背景颜色,并且项目改变了他在 ListBox 中的顺序。

例如,如果我有:

  1. 项目 1
  2. 项目 2
  3. 项目 3

滚动后我有:

  1. 项目 2
  2. 项目 3
  3. 项目 1

此更改是随机的。每次都不一样。

实例(处理步骤):

  1. 加载 Main class ListBox 所在的位置。

  1. 垂直向下滚动以查看其余项目。

  2. 垂直向上滚动到 return 到列表顶部。

  1. 列表框中的项目改变了位置,按钮(每个项目的组件)改变了它的背景颜色。

为什么我在 ListBox 中有这种行为??我该如何解决它并且 ListBox 不更改项目顺序既不更改其组件的背景颜色?

我不知道是否有任何 属性 来阻止 ListBox 或类似的项目...

编辑

这是创建和初始化列表框项目的代码:

procedure TRooms_Form.FormCreate(Sender: TObject);
var
  ...
begin
    i := 0;
    while i < numItems do begin
      //Create ListBox item
       item := TListBoxItem.Create(nil);
       item.Parent := myListBox;
       item.StyleLookup := 'styleLBox';
      //Number
       itemNumber := item.FindStyleResource('btt_number') as TButton;
       if Assigned(itemNumber) then begin
           itemNumber.Text := jsonNumber;
           case jsonColor of
             0 : itemNumber.TintObject.TintColor := TAlphaColors.Chocolate; 
             1 : itemNumber.TintObject.TintColor := TAlphaColors.Gold;      
             2 : itemNumber.TintObject.TintColor := TAlphaColors.Darkgreen; 
             3 : itemNumber.TintObject.TintColor := TAlphaColors.Deeppink;  
           end;
         end;
      //Title
       itemTitle := item.FindStyleResource('txtstyle_title') as TText;
       if Assigned(itemTitle) then begin
         itemTitle.Text := jsonTitle;
       end;
      //Occupation
       itemOccup := item.FindStyleResource('txt_occupation') as TText;
       if Assigned(itemOccup) then begin
         itemOccup.Text := jsonOccup;
       end;
      //Dates
       itemDay := item.FindStyleResource('txt_day') as TText;
       if Assigned(itemDay) then itemDay.Text := displayDay;
       itemDateStart := item.FindStyleResource('txt_start') as TText;
       if Assigned(itemDateStart) then itemDateStart.Text := jsonTimeStart;
       itemDateEnd := item.FindStyleResource('txt_end') as TText;
       if Assigned(itemDateEnd) then itemDateEnd.Text := jsonTimeEnd;
      //Item background
       itemBackgr := item.FindStyleResource('background_item') as TRectangle;
       if Assigned(itemBackgr) then begin
         itemBackgr.Fill.Kind := TBrushKind.Solid;
         case jsonStatus of
           0 : itemBackgr.Fill.Color := TAlphaColors.White;         
           1 : itemBackgr.Fill.Color := TAlphaColors.Lightgreen;    
           2 : itemBackgr.Fill.Color := TAlphaColors.Palegoldenrod; 
           3 : itemBackgr.Fill.Color := TAlphaColors.Lightcoral;    
           4 : itemBackgr.Fill.Color := TAlphaColors.Lightseagreen; 
           5 : itemBackgr.Fill.Color := TAlphaColors.Lightblue;     
           6 : itemBackgr.Fill.Color := TAlphaColors.Lightgrey;     
         end;
       end;
      //Empty item
       if (StrToInt(jsonEmpty) = 1) or (StrToInt(jsonNull) = 1) then begin
         startDetail[i] := False;
         if Assigned(itemNumber) then itemNumber.Visible := False;
         if Assigned(itemOccup) then itemOccup.Visible := False;
       end
       else begin
         startDetail[i] := True;
       end;

       Inc(i);
    end;

非常感谢您的关注。

经过几天和一些测试,我已经找到了解决问题的方法。

我不太明白为什么,但有一些代码行干扰了我的自定义样式。

例如,当我输入:

//Item background
   itemBackgr := item.FindStyleResource('background_item') as TRectangle;
   if Assigned(itemBackgr) then begin
     **itemBackgr.Fill.Kind := TBrushKind.Solid;**
     ...

滚动后,项目更改了顺序位置及其颜色背景。我在自定义样式的'TRectangle'组件中直接应用了这个属性。

另外,我把所有元素的分配改成了这样:

-之前我有:

   itemTitle := item.FindStyleResource('txtstyle_title') as TText;
   if Assigned(itemTitle) then begin
     itemTitle.Text := jsonTitle;
   end;

-现在,我有:

   item.StylesData['txtstyle_title'] := jsonTitle;

通过这些更改,我得到的项目在滚动后不会更改它们在 ListBox 中的位置,也不会更改背景颜色。

我遇到了一个问题,按钮不显示它们的背景颜色,这是由于这些行造成的:

//Empty item
   if (StrToInt(jsonEmpty) = 1) or (StrToInt(jsonNull) = 1) then begin
     startDetail[i] := False;
     **if Assigned(itemNumber) then itemNumber.Visible := False;**
     **if Assigned(itemOccup) then itemOccup.Visible := False;**
   end
   else begin
     startDetail[i] := True;
   end;

显然,您无法在 'FormCreate' 方法中更改项目的可见 属性,因为当您滚动某些项目时,某些项目元素会在不受控制的情况下更改其 属性。因此,我对我的代码做了一些修改,而不是将可见性设置为 false:

    if (StrToInt(jsonEmpty) = 1) or (StrToInt(jsonNull) = 1) then begin
      startDetail[i] := False;
      item.StylesData['btt_number.Text'] := '';
      item.StylesData['txt_occupation'] := '';
      if (StrToInt(jsonEmpty) = 1) then item.StylesData['btt_number.TintObject.TintColor'] := TAlphaColors.White;
      if (StrToInt(jsonNull) = 1) then item.StylesData['btt_number.TintObject.TintColor'] := TAlphaColors.Lightblue;
    end
    else begin
      startDetail[i] := True;
      item.StylesData['btt_number.Text'] := jsonNumber;
      item.StylesData['txt_occupation'] := jsonOccup;
    end;

在这种形式下,我将文本“ ”(空)和背景颜色设置为与他的项目(TRectangle)在应该具有可见性的元素中相同的颜色 属性 为 false。

在所有这些更改之后,我得到了我想要的结果,也就是说,当我滚动时,我的项目列表框没有改变。 XD

将表单上的样本更改为资源 1 对我很有帮助。