Проблема перекраски объекта FM2
Добрый вечер ребята.
В настоящее время я разрабатываю клиент для социальных сетей для Twitter и Facebook в Firemonkey FM2
(Delphi), и я испытываю неприятную проблему. В настоящее время у меня работает только код Twitter, но проблема связана с [пере] рисованием визуальных объектов.
Я создал пользовательский стиль TListboxItem
макет в книге стилей, состоящей из нескольких дочерних компонентов, таких как TText
, TButton
, а также TImage
, Я уже имел дело с подключением к Твиттеру и получением информации о фиде. Каждый полученный предмет добавляется в TListbox
и стилизованный, используя мой собственный макет стиля ListboxItem.
Теперь проблема связана с обновлением информации о невидимых элементах списка. Например, элементы, которые отображаются в списке без прокрутки, показывают свою информацию правильно. Те, которые не видны, кроме последнего элемента в списке, имеют некоторые детали, которые не установлены / не видны. Когда я прокручиваю список вниз, а затем возвращаюсь назад, часто один из элементов, которые были изначально видны, теперь теряет свою информацию.
Чтобы объяснить это немного подробнее, у меня есть изображение (известное как фотография), которое используется, чтобы показать фотографию человека, который разместил "твит". У меня есть стандартный TText (известный как текст), используемый для отображения содержимого / текста самого твита. У меня есть 2 кнопки (известные как Like и Share), используемые для выполнения их соответствующих функций. Затем я наконец получил еще один TText (известный как NameDate), используемый для отображения названия твитера и даты его публикации.
Я использую этот код для создания объекта и изменения данных, которые он показывает;
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
является стандартным компонентом HTTP-клиента ICS, а TwitObj - моим компонентом Twitter. Вы можете видеть, что я сохраняю фотографию в каталог вместо потоковой передачи. Это было просто для того, чтобы проверить, была ли это проблема с потоками, но в любом случае, вероятно, целесообразно использовать какой-то кэш.
Изображения загружаются правильно, и информация для соответствующих StyleResources в пользовательском макете ListBoxItem обновляется, как ожидается, но только для элементов, которые видны без прокрутки. Если прокрутить список вниз, только Text
каждого элемента является правильным, в то время как другие ресурсы, которые были установлены во время выполнения, вернулись к тому, как они спроектированы в книге стилей (то есть к пустому тексту, изображению и т. д.).
Я что-то здесь упускаю? Я понимаю, что конструктивные намерения Bitmaps были изменены в XE3 ради производительности, но, конечно, Embarcadero не упустил бы что-то подобное. Конечно, мы не ожидаем, что мы создадим каждый элемент внутри родителя во время выполнения (и, следовательно, будем работать с выравниваниями и т. Д.) Вместо использования ресурса книги стилей, не так ли?
Любая помощь или понимание будет принята с благодарностью.
1 ответ
FireMonkey может загружать и выгружать стиль для элемента управления в любой момент. Это было довольно слабо в FM1, но в FM2 элементы оформления удаляются, когда элемент управления не виден, и повторно применяются, когда он снова становится видимым (для сохранения памяти, главным образом при подготовке к Mobile Studio).
Что вам нужно сделать, это переопределить метод ApplyStyle. В ней ищите и устанавливайте данные в ваших элементах стиля. Это, вероятно, будет означать, что ваши элементы управления должны кэшировать то, что будет передано стилю.
Также обратите внимание, что если вы кешируете ссылки на элементы стиля (то есть, что вы получаете от FindStyleResource), то они будут освобождены, когда стиль выгружен, а ваши указатели будут недействительными. Если это так, вам нужно переопределить FreeStyle и обнулить любые указатели, которые вы, возможно, кэшировали.