Просмотр полной версии : TextArea, ScrollEvent.SCROLL и вообще про события во Flex
Подскажите плз. почему когда листенишь ScrollEvent.SCROLL у TextArea то verticalScrollPosition показывает значение предыдущщего скроллинга, и какое событие нужно листенить чтобы после скролла получить реально значение verticalScrollPosition и других свойств
TextArea.
спасибо
Кажется, там нужен validateNow выполнить. Не смотрел.
да, слышал про такую штуку :)
validateNow называется,
пробовал - не помогает.
не буду приводить код полностью но в целом проблема сводится вот к такой:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.events.ScrollEvent;
private function ta_scroll(e:ScrollEvent) {
ta.validateNow();
trace("verticalScrollPosition: " + ta.verticalScrollPosition);
//trace(e.position);
}
]]>
</mx:Script>
<mx:TextArea id="ta" text="kykykykykykkyykykkykykykykykykykykykykykkykykyky"
width="100" height="50" scroll="ta_scroll(event);" >
</mx:TextArea>
</mx:Application>
ну так вот в этом примере ta.verticalScrollPosition выдаёт неправильное значене.
Заглянул в сорцы TextArea и увидел там любопытные строчки:
override protected function scrollHandler(event:Event):void
{
// TextField.scroll bubbles so you might see it here
if (event is ScrollEvent)
{
if (!liveScrolling &&
ScrollEvent(event).detail == ScrollEventDetail.THUMB_TRACK)
{
return;
}
super.scrollHandler(event);
textField.scrollH = horizontalScrollPosition;
textField.scrollV = verticalScrollPosition + 1;
_vScrollPosition = textField.scrollV - 1;
_hScrollPosition = textField.scrollH;
}
}
А внутри ScrollControlBase:
protected function scrollHandler(event:Event):void
{
// TextField.scroll bubbles so you might see it here
if (event is ScrollEvent)
{
var scrollBar:ScrollBar = ScrollBar(event.target);
var pos:Number = scrollBar.scrollPosition;
var prop:QName;
if (scrollBar == verticalScrollBar)
prop = new QName(mx_internal, "_verticalScrollPosition");
else if (scrollBar == horizontalScrollBar)
prop = new QName(mx_internal, "_horizontalScrollPosition");
dispatchEvent(event);
if (prop)
this[prop] = pos;
}
}
Т.е. событие для скролла вызывается до того, как свойство изменилось в самом TextArea. Как это обходить, я не знаю, жди спецов по флексу.
Кстати, event.position выдает верное значение. Что мешает его использовать?
Дело в том что я пытаюсь добавить смайлы в этот самый TextArea,
для этого экстендю TextArea, и делаю внутренний TextField публичным.
У TextField есть метод - getCharBoundaries, который возвращает Rectangle в котором находится определённая буква ( в моём случае - смайл ).
Так вот после скролла этот метод getCharBoundaries внетреннегно текстфилда тоже выдаёт неправильное значение :(
Спасибо большое за ответ, думаю теперь я разберусь.
Тебе нужно отложить выполнение до следующего кадра хотя бы. Или на некоторое кол-во миллисекунд. Или переписать scrollHandler.
удобно таком случае пользоваться callLater -
callLater(function():void
{
....
});
Примерчик заодно:
http://livedocs.macromedia.com/flex/2/docs/00001438.html
Хотя, раз наследуемся от TextArea, то можно и переписать scrollHandler. Не знаю, правда, может это к глюкам каким-нибудь привести или нет…
в своём классе наследующем TextArea делаю примерно так:
override protected function scrollHandler(event:Event) : void {
super.scrollHandler(event);
dispatchEvent(new Event("afterScroll",false,false));
}
всё вроде работает, verticalScrollPosition пашет, всё остальное тоже, но теперь другая беда - когда текст вмещается в TextArea полностью, почемуто всёравно появляется скролл и естественно всё портит :(
verticalScrollPolicy поменял на on - ничего не изменилось. :)
так по умолчанию итак auto.
фишка в том что возникает ситуация когда verticalScrollPosition меняется а положение текста - нет.
Это как-нибудь связано с тем, что ты переписал scrollHandler или нет?
нет... это всегда такое поведение у TextArea.
из хелпа:
Line number of the top row of characters that is currently displayed. The default value is 0.
на самом деле это не так, легко увидеть если просто в TextArea вбить текст который помещается в неё - скролл будет, будет меняться verticalScrollPosition, но текст , а соответственно и номер верхней строки будут оставаться на месте.
Ну опять же, ты можешь переписать любую часть TextArea так, как нужно.
Ну опять же, ты можешь переписать любую часть TextArea так, как нужно.
Еще раз подтвердив любовь Адоба к разработчикам
Ну как есть, я уже начинаю радоваться, что я не работаю с компонентами постоянно, а только вот в таких случаях :D
Ковыряться в чужих классах и искать косяки занятие не очень благодарное :D
проблема решилась использованием scrollV внутреннего текстфилда TextArea вместо verticalScrollPosition.
Теперь решаем другую - не срабатывает событие скролла если скролить
колесом - будем думать :)
Вот они, флексовые компоненты :D
Ну я могу лишь посоветовать подписать scrollHandler. Хотя он вообще-то работает при скролле. Видимо, ты где-то что-то переопределил.
помогите разобратся плз. похоже я не допонимаю чего-то :)
TextArea наследуется от ScrollControlBase, при этом в конструкторе ScrollControlBase приписывается листенер для MouseEvent.MOUSE_WHEEL,
mouseWheelHandler:
protected function mouseWheelHandler(event:MouseEvent):void
{
// If this Container has a vertical scrollbar,
// then handle the event and prevent further bubbling.
if (verticalScrollBar)
{
event.stopPropagation();
var scrollDirection:int = event.delta <= 0 ? 1 : -1;
// Make sure we scroll by at least one line
var scrollAmount:Number = Math.max(Math.abs(event.delta),
verticalScrollBar.lineScrollSize);
// Multiply by 3 to make scrolling a little faster
var oldPosition:Number = verticalScrollPosition;
verticalScrollPosition += 3 * scrollAmount * scrollDirection;
var scrollEvent:ScrollEvent = new ScrollEvent(ScrollEvent.SCROLL);
scrollEvent.direction = ScrollEventDirection.VERTICAL;
scrollEvent.position = verticalScrollPosition;
scrollEvent.delta = verticalScrollPosition - oldPosition;
dispatchEvent(scrollEvent);
}
}
в классе TextArea он переопределяется:
override protected function mouseWheelHandler(event:MouseEvent) : void {
event.stopPropagation();
}
Вопрос - каким образом TextArea реагирует на Wheel если mouseWheelHandler переопределён и ничего не делает ?
реагирует текстовое поле которое находиться в текст арии, а текст ария слушает это событие у этого текстового поля (это я так предположил :D)
lephik, но TextField-у не прикажешь, он крутится же)
а... блин панял спасибо чуваки ;)
похоже всётаки не зря адобы в SDK сорсы фреймворка запхали....
похоже всётаки не зря адобы в SDK сорсы фреймворка запхали....
Если бы они этого не сделали то была бы нам полная Ж! И вообще фиг бы кто повелся програмить на флекс
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.