Scroll to alphabet in a List (ArrayCollection dataProvider) (Alphabet Jump)
Hopefully this is easy but that sometimes means its impossible in flex and I have searched quite a bit to no avail.
Say I have a list (LIST#1) of artists:
2Pac Adele Amerie Beyonce Jason Aldean Shakira The Trews
I also have a list (LIST#2) that has the values #,A-Z - how would I create an alphabet jump?
So If a user clicked on "A" in LIST#2 that would automatically scroll to "Adele" at the top of LIST#1 - not filter so he/she could scroll up to view 2Pac or down to view The Tews if they were not in the view yet.
Its a standard Flex Spark List with an ArrayCollection as the dataProvider - the artist field is called: "title" along with a unique id field that is not visible to the user.
Thanks!
Please see comments on marker answer for discussion on Dictionary that may be faster in some cases. See below for code (HAVE NOT CONFIRMED ITS FASTER! PLEASE TEST):
private function alphabet_listChange(evt:IndexChangeEvent) : void {
var letter:String;
letter = evt.currentTarget.selectedItems[0].toString();
trace(currentDictionary[letter]);
ui_lstLibraryLi开发者_开发知识库st.ensureIndexIsVisible(currentDictionary[letter]);
}
public function createAlphabetJumpDictionary() : Dictionary {
//alphabetArray is a class level array containing, A-Z;
//alphabetDictionary is a class level dictionary that indexes A-z so alphabetDictionary["A"] = 0 and ["X"] = 25
var currentIndexDict:Dictionary = new Dictionary; //Dictionary is like an array - just indexed for quick searches - limited to key & element
var searchArray:Array = new Array;
searchArray = currentArrayCollection.source; //currentArrayCollection is the main array of objects that contains the titles.
var currentIndex:Number; //Current index of interation
var currentAlphabetIndex:Number = 0; //Current index of alphabet
for (currentIndex = 0; currentIndex < searchArray.length; currentIndex++) {
var titleFirstLetter:String = searchArray[currentIndex].title.toString().toUpperCase().charAt(0);
if (titleFirstLetter == alphabetArray[currentAlphabetIndex]) {
currentIndexDict[titleFirstLetter] = currentIndex;
trace(titleFirstLetter + " - " + currentIndex);
currentAlphabetIndex++;
} else if (alphabetDictionary[titleFirstLetter] > alphabetDictionary[alphabetArray[currentAlphabetIndex]]) {
trace(titleFirstLetter + " - " + currentIndex);
currentIndexDict[titleFirstLetter] = currentIndex;
currentAlphabetIndex = Number(alphabetDictionary[titleFirstLetter] + 1);
}
}
return currentIndexDict;
}
private function build_alphabeticalArray() : Array {
var alphabetList:String;
alphabetList = "A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z";
alphabetArray = new Array;
alphabetArray = alphabetList.split(".");
return alphabetArray;
}
private function build_alphabetDictionary() : Dictionary {
var tmpAlphabetDictionary:Dictionary = new Dictionary;
for (var i:int=0; i < alphabetArray.length; i++) {
tmpAlphabetDictionary[alphabetArray[i]] = i;
trace(alphabetArray[i] + " - " + i);
}
return tmpAlphabetDictionary;
}
private function buildCurrentDictionary() : void {
trace("Collection Changed");
currentDictionary = new Dictionary;
currentDictionary = createAlphabetJumpDictionary();
}
The Flex Spark list has a very convenient method called ensureIndexIsVisible(index)
. Check the Flex reference documentation. All you have to do is to find the index of the first artist for the corresponding selected alphabet letter:
public function findAlphabetJumpIndex():Number
{
var jumpToIndex:Number;
var selectedLetter:String = alphabethList.selectedItem;
for (var i:int=0; i < artists.length; i++)
{
var artistName:String = artists.getItemAt(i);
var artistFirstLetter:String = artistName.toUpperCase().charAt(0);
if (artistFirstLetter == selectedLetter)
{
jumpToIndex = i;
break;
}
}
return jumpToIndex;
}
You can iterate your artist list data provider and check if artist name starts with selected alphabet from list two. When corresponding artist is found, set artist list selected index a value what you get from iterating data.
精彩评论