Я работаю с цифровым книжным приложением. Я использую swf-загрузчик для загрузки swf-страниц, созданных из pdf. Я использую TextSnapsot для выделения выделенного текста на страницах. Выделение тщательно сохраняется на соответствующих страницах в течение всего сеанса, а затем оно может быть обновлено/удалено без каких-либо проблем. Все работало отлично, пока я не сделал следующие изменения в подходе к загрузке swf, чтобы включить кеширование страниц:Проблема выделения текста с объектом TextSnapshot - Flex AS3
Теперь я загружаю объект загрузчика swf в память приложения и при переходе с одной страницы на другую страницу я просто копирую содержимое следующей страницы к текущему swf-загрузчику, который отображается на дисплее пользователю. Существует два набора swf-загрузчиков - один для отображения страницы, а другой - для кеширования следующей/предыдущей страницы. На стороне кэширования я загружаю swf в память приложения, и после его загрузки я выбираю все содержимое загруженной swf-страницы (дочерних элементов этого мувиклипа) в массив массивов. При изменении страницы я копирую кешированный контент в мувиклип swf-загрузчика, который отображает страницу.
Теперь, когда я выделяю на странице на дисплее и перемещаюсь назад/вперед со страницы и снова возвращаюсь на страницу, где я делал выделение: он показывает выделение, которое я сделал. Но как только я попытаюсь сделать еще одну подсветку на этой странице, предыдущая подсветка моментально исчезает со страницы.
Я подозреваю, что объект Textsnapshot, который выделяет выделение во время навигации (на целевую страницу отображения), отличается от того, который в следующий раз перерисовывает/обновляет выделение на той же странице. Хотя идентификатор объекта Textsnapshot для обоих объектов одинаковый.
Вот некоторые фрагменты кода:
Для копирования содержимого из объекта SWF загрузчика кэшируется в памяти приложения:
private function copyPageContent():void
{
var contentCollection:ArrayCollection = new ArrayCollection();
_pageContentVO = new PageContentVO();
_pageContentVO.contentHeight = MovieClip(_swfPageLoader.content).height;
_pageContentVO.contentWidth = MovieClip(_swfPageLoader.content).width;
var count:int = MovieClip(_swfPageLoader.content).numChildren;
for(var i:int=0;i<count;i++)
{
var dispObject:DisplayObject = MovieClip(_swfPageLoader.content).removeChildAt(0);
contentCollection.addItem(dispObject);
}
_pageContentVO.pageContentCollection = contentCollection;
_swfPageLoader = null;
}
Для копирования содержимого в SWF-загрузчик, который отображает страницу:
private function copyContent(pageContentVo:PageContentVO):void
{
for(var i:int = 0;i<pageContentVo.pageContentCollection.length;i++)
{
var dispObject:DisplayObject = pageContentVo.pageContentCollection.getItemAt(i) as DisplayObject;
MovieClip(this.content).addChild(dispObject);
}
this.content.height = this.height;
this.content.width = this.width;
}
после этого отправка посылкой swf полностью вручную и в обработчике этого события. Я беру текст объекта snap shot. (HighlightManager.as)
Код, который я использую, чтобы нарисовать выделение вручную (используя перетаскивание мышью на странице).
public function setHighlight():void
{
removeAll();
if(_textSnapShot!=null && _textSnapShot.getText(0,_textSnapShot.charCount)!="")
{
if(_isCoveredTextSelectedAtAnyInstance)
{
_textSnapShot.setSelected(_beginIndex,_endIndex+1,false); //this is the global variable to the class
}
else
{
_textSnapShot.setSelectColor(0xfff100);
_textSnapShot.setSelected(_beginIndex,_endIndex+1,true);
}
if(saveHighlight)
{
countHighlightedSegments();
}
}
}
код я использую, чтобы перерисовать ранее нарисованный блик, когда я вернусь к странице:
public function showHighlights(textSnapShot:TextSnapshot,currentPageNum:int):void
{
if(currentPageNum >= 0)
{
textSnapShot.setSelected(0,textSnapShot.charCount,false);
var pageVO:PageVO = _model.eBookVO.eBookPagesVO.getItemAt(currentPageNum) as PageVO;
var objColl:ArrayCollection = new ArrayCollection();
objColl.source = pageVO.highLightSelection;
for(var i:int=0;i<objColl.length;i++)
{
var highlightVO:HighlightVO = new HighlightVO();
highlightVO.beginIndex = objColl.getItemAt(i).beginIndex;
highlightVO.endIndex = objColl.getItemAt(i).endIndex;
setHighlightedSegment(textSnapShot,highlightVO.beginIndex,highlightVO.endIndex);
}
}
}
private function setHighlightedSegment(textSnapShot:TextSnapshot,beginIndex:int,endIndex:int):void
{
textSnapShot.setSelectColor(0xfff100);
textSnapShot.setSelected(beginIndex,endIndex,true);
}
Заглядывая вперед к вашей поддержке, чтобы решить эту проблему.
С уважением,
JS
Привет, JAX благодарит за быстрый и внушающий ответ ответ. Первоначальный подход был тем, что вы предложили в первую очередь, но я уже пробовал ваш второй подход. Это улучшило загрузку, но мое требование по-прежнему требует даже более быстрой загрузки. С моим подходом все функциональные возможности моего приложения работают прекрасно, с гораздо лучшими возможностями для пользователя, но особенность подсветки. Любые другие предложения по этой проблеме? –
Проверьте, сколько времени он «загружает», используя консоль разработчика хром, или firebug в firefox. если он кэширован, для доступа к нему на жестком диске требуется очень мало времени и добавить его в SWF. Там, где может возникнуть проблема (и, по моему мнению, это ошибка), это тот факт, что после его загрузки все еще требуется инициализация загруженного SWF. Я бы подумал, что это то, что занимает больше всего времени. Что вам нужно сделать, это попытаться оптимизировать упомянутый swf для загрузки как можно быстрее. Вы можете предварительно инициализировать его, используя 3 SWF-загрузчика, а затем поменять их в зависимости от того, что просматривается. –
Привет, JAX, еще раз спасибо за наводящий ответ, Позвольте мне сначала сказать, что моя проблема решена. Это была проблема с textSnapShot GC. Я просто добавил объект textnapshot в массив, чтобы избежать GC, и это решило мою проблему. Теперь я прихожу к вашему предложению - я делаю именно то, что вы говорите («Вы можете предварительно инициализировать его, используя 3 SWF-загрузчика, а затем поменяв их в зависимости от того, что просматривается»), но вместо замены swfs я заменяю содержимое отображаемого SWF с содержимым предварительной инициализации swf. Поскольку для swap swfs было что-то против структуры моих приложений –