Я новичок в Flex / ActionScript (до сих пор моей основной игровой площадкой была .NET / Java). Я пытаюсь создать приложение Flex, у которого есть список, который должен выглядеть и вести себя как бесконечный список (элементов - который может быть любым). Идея состоит в том, что пользователь должен иметь возможность прокручивать вверх или вниз и никогда не доходить до конца списка в любом направлении.
Примером может служить список чисел. Прокрутка вверх покажет отрицательные числа; прокрутка вниз покажет положительные. Теперь мой список представляет собой простой список Flex Spark (с использованием Flex Hero). Он привязан к поставщику данных, который является ArrayList.
Моя первоначальная идея заключалась в том, чтобы прослушивать событие прокрутки и добавлять / удалять элементы по мере необходимости. Однако в текущей сборке Flex Hero есть ошибка, которая иногда не вызывает события прокрутки для вертикальных полос прокрутки (http://bugs.adobe.com/jira/browse/SDK-26533).
Итак, я использую обходной путь, предложенный в приведенной выше ссылке (например, прослушивание события propertyChanged окна просмотра прокрутки списка. Событие, однако, дает мне только текущее значение verticalScrollPosition.
И похоже, что список искр по умолчанию поддерживает плавную прокрутку и вызывает событие много раз, прежде чем прокрутка списка остановится (это хороший визуальный эффект).
Теперь мне нужно:
- Выясните, прокручивается ли он вверх или вниз (как мне это сделать?)
Выясните, какие элементы видны. Я могу получить это из:
list.dataGroup.getItemIndicesInView()
Добавляйте / удаляйте элементы по мере необходимости, чтобы пользователь мог бесконечно прокручивать вверх и вниз, никогда не доходя до конца списка ни в одном направлении.
Я пробовал следующий код, но он не работает. (комментарии в коде).
Есть какие-нибудь эксперты по Flex? Пожалуйста помоги.
import mx.collections.ArrayList;
import mx.core.INavigatorContent;
import mx.events.FlexEvent;
import mx.events.PropertyChangeEvent;
var listData:ArrayList;
var firstItemInView:int = 0;
var lastItemInView:int = 0;
var count = 0;
//gets the currently visible item indices (first and last)
private function getVisibleIndices():Vector.<int> {
var ind:Vector.<int> = new Vector.<int>(2, true);
ind[0] = firstItemInView;
ind[1] = lastItemInView;
return ind;
}
protected function view_creationCompleteHandler(event:FlexEvent):void {
//create an initialise list data
listData = new ArrayList();
for(var i:int = 0; i < 6; i++){
listData.addItemAt(i, i);
}
infiniteList.dataProvider = listData;
updateIndices();
infiniteList.scroller.viewport.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, infiniteList_VerticalScroll_PropertyChanged);
}
//get the indices visible from the list's data group
private function getNewIndices():Vector.<int> {
var indices:Vector.<int> = new Vector.<int>(2, true);
var indicesInView:Vector.<int> = infiniteList.dataGroup.getItemIndicesInView();
if (indicesInView.length > 0){
indices[0] = indicesInView[0];
}
if (indicesInView.length > 1){
indices[1] = indicesInView[indicesInView.length - 1];
}
return indices;
}
private function updateIndices():void {
var indices:Vector.<int> = getNewIndices();
if (indices.length > 0){
firstItemInView = indices[0];
if (indices.length > 1){
lastItemInView = indices[1];
}
}
}
protected function leftCalendar_VerticalScroll_PropertyChanged(event:PropertyChangeEvent):void {
switch (event.property){
case "verticalScrollPosition":
var indices:Vector.<int> = getNewIndices();
var oldIndices:Vector.<int> = getVisibleIndices();
var newNum:Number;
if (indices[1] - indices[0] == 2 && (oldIndices[0] != indices[0] && oldIndices[1] != indices[1])){
//a new item is in view. did we scroll up or down?
if (oldIndices[0] < indices[0]){
count++;
trace(count + " up : old[" + oldIndices[0] + "," + oldIndices[1] + "], new[" + indices[0] + "," + indices[1] + "]");
//newNum = Number(listData.getItemAt(listData.length - 1)) + 1;
//trace("new number to add: " + newNum);
//trace("todo remove: " + listData.getItemAt(0));
fixItems({ addAt : "top", removeAt : "bottom", newValue : newNum});
} else {
trace("down : old[" + oldIndices[0] + "," + oldIndices[1] + "], new[" + indices[0] + "," + indices[1] + "]");
fixItems({ addAt : "bottom", removeAt : "top", newValue : newNum});
}
//update indices:
updateIndices();
var newOnes = getVisibleIndices(); //seems to be getting the new ones, but the next occurance of this event handler doesn't pick up the new values! why?
trace(count + " current[" + newOnes[0] + ", " + newOnes[1] + "]");
}
break;
}
}
protected function fixItems(data:Object):void {
var item:Object;
//add a new item
if (data.addAt == "top"){
listData.addItemAt(data.newValue, 0);
} else {
listData.addItem(data.newValue);
}
//remove one of the existing ones
if (data.removeAt == "top"){
item = listData.getItemAt(0);
trace("removing " + item);
listData.removeItemAt(0);
} else {
item = listData.getItemAt(listData.length - 1);
trace("removing " + item);
listData.removeItemAt(listData.length - 1);
}
updateIndices();
}