1

Good evening guys.

I'm currently designing a social networking client for Twitter and Facebook in Firemonkey FM2 (delphi) and I'm experiencing a frustrating issue. At present, I've only got the Twitter code in process, but the issue is related to the [re]drawing of visual objects.

I've created a custom-styled TListboxItem layout in a stylebook consisting of multiple child components such as TText, TButton, and TImage. I've already dealt with connecting to Twitter and retrieving feed details. Each item retrieved is added to a TListbox and styled using my custom ListboxItem style layout.

Now, the issue is related to updating information on items in the list that aren't visible. For example, the items that are visible in the list without scrolling show their information correctly. Those that aren't visible besides the final item in the list have several of their details not set/visible. When I scroll the list downwards, and then back up, there's often 1 of the items that was originally visible will now be missing it's information.

To explain this a little more, i've got a TImage (known as photo) which is used to show the photo of the person who posted the 'tweet'. I've got the standard TText (known as text) used to show the contents/text of the tweet itself. I've got 2 buttons (known as Like and Share) used to perform their respective functions. I've then finally got another TText (known as NameDate) used to show the name of the tweeter and the date the tweet was posted.

I'm using this code to create the object and modify the data it shows;

 for i := 0 to TwitObj.Statuses.Count-1 do
  begin
    FeedItem := TListBoxItem.Create(LBFeed);
    FeedItem.Parent := LBFeed;
    FeedItem.StyleLookup := 'FeedItem';
    FeedItem.WordWrap := True;
    FeedItem.StyledSettings := [TStyledSetting.ssFamily, TStyledSetting.ssSize, TStyledSetting.ssStyle, TStyledSetting.ssFontColor, TStyledSetting.ssOther];
    NameDate := Feeditem.FindStyleResource('txtnamedate') as TText;
    Photo := FeedItem.FindStyleResource('photo') as TImage;
    Like := FeedItem.FindStyleResource('btnlike') as TButton;
    Share := FeedItem.FindStyleResource('btnshare') as TButton;
    Share.Text := 'Retweet';
    Like.Text := 'Favorite';
    NameDate.Text := Twitobj.Statuses.Items[i].User.Name +
                     '(@'+TwitObj.Statuses.Items[i].User.ScreenName+
                     ') - '+DateTimeToStr(TwitObj.Statuses.Items[i].CreatedAt);
    FeedItem.Text := TwitObj.Statuses.Items[i].Text;

    begin
      if DirectoryExists('imagecache\') = false then CreateDir('imagecache\');
      if FileExists('imagecache\'+TwitObj.Statuses.Items[i].User.ScreenName+'.jpg') = False then
      begin
        try
          rcv := TMemoryStream.Create;
          GtPhoto.URL := TwitObj.Statuses.Items[i].User.ImageURL;
          GtPhoto.RcvdStream := rcv;
          GtPhoto.Get;
          rcv.SaveToFile('imagecache\'+TwitObj.Statuses.Items[i].User.ScreenName+'.jpg');
        finally
          Rcv.Free;
        end;
      end;
    end;
    Photo.Bitmap.LoadFromFile('imagecache\'+TwitObj.Statuses.Items[i].User.ScreenName+'.jpg');

GTPhoto is a standard ICS HTTP Client component, while TwitObj is my Twitter component. You can see that I'm saving the photo to a directory instead of streaming it. This was merely to check whether it was an issue with streams, but it's probably advisable to used a cache of some sort anyway.

The images download correctly, and the information for the relevant StyleResources in the custom ListBoxItem layout is updated as expected, but only for items that are visible without scrolling. If I scroll down the list, only the Text of each item is correct, while the other resources which were set at runtime have returned to the way they're designed in the stylebook (i.e. blank text, image, etc).

Am I missing something here? I understand the design intents of Bitmaps were changed in XE3 for the sake of performance, but surely Embarcadero wouldn't have overlooked something like this. Surely it's not expected for us to create each item inside the parent at runtime (and thus dealing with alignments and such) instead of using a stylebook resource, is it?

Any assistance or insight would be greatly appreciated.

4

1 回答 1

1

FireMonkey 可以随时加载和卸载控件的样式。这在 FM1 中相当松懈,但在 FM2 中,当控件不可见时会删除样式元素,并在控件再次可见时重新应用(为了节省内存,主要是为 Mobile Studio 做准备)。

您需要做的是覆盖 ApplyStyle 方法。在其中查找并设置样式元素中的数据。这可能意味着您的控件需要缓存将传递给样式的内容。

另请注意,如果您正在缓存对样式元素的引用(即您从 FindStyleResource 返回的内容),那么当样式被卸载并且您的指针将无效时,这些将被释放。如果是这样,您需要覆盖 FreeStyle 并清除您可能缓存的任何指针。

于 2013-01-15T20:23:50.690 回答