最近工作中遇到的问题,客户要求做这么个东西。还是稍微花了点时间做了个DEMO的,凭记忆回来整理出来,以供以后查阅。
方法其实很简单,就是自己写代码判断用户选的开始的位置和结束的位置,然后把中间的都选中就OK了。但是做起来,确实还是需要小心些的。
简单来说,这个DEMO中有3个List,但是用户会感觉在操作一个List,尤其是在多选的时候。
支持SHIFT选一段,CTRL一个一个选,以及CTRL+A选全部。
不废话,上代码和图~
SelectItemVO.as
================
package
{
// this class is used to set the data of first selection and second selection
public class SelectItemVO
{
public function SelectItemVO()
{
}
private var _listID:String="";
private var _itemIndex:int=-1;
// used to get/set item index
public function get itemIndex():int
{
return _itemIndex;
}
public function set itemIndex(value:int):void
{
_itemIndex=value;
}
// used to get/set list id
public function get listID():String
{
return _listID;
}
public function set listID(value:String):void
{
_listID=value;
}
// used to set value
public function setValue(id:String, index:int):void
{
_listID=id;
_itemIndex=index;
}
public function clean():void
{
_listID="";
_itemIndex=-1;
}
}
}
ListDemo.mxml
===========
flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
minWidth="955"
creationComplete="init(event)"
fontFamily="Verdana"
minHeight="600">
=new Vector.();
for (var i:int=start; i ();
if (doAll || (startItem.listID != LIST3 && endItem.listID != LIST3))
list3.selectedIndices=new Vector.();
break;
case LIST2:
if (doAll)
{
list1.selectedIndex=-1;
list3.selectedIndex=-1;
}
if (doAll || (startItem.listID != LIST1 && endItem.listID != LIST1))
list1.selectedIndices=new Vector.();
if (doAll || (startItem.listID != LIST3 && endItem.listID != LIST3))
list3.selectedIndices=new Vector.();
break;
case LIST3:
if (doAll)
{
list1.selectedIndex=-1;
list2.selectedIndex=-1;
}
if (doAll || (startItem.listID != LIST1 && endItem.listID != LIST1))
list1.selectedIndices=new Vector.();
if (doAll || (startItem.listID != LIST2 && endItem.listID != LIST2))
list2.selectedIndices=new Vector.();
break;
default:
break;
}
}
// handle user's clicking on list item (when list's select item is changing)
protected function changingHandler(event:IndexChangeEvent):void
{
var list:List=event.target as List;
if (isShiftDown) // handle SHIFT - select first
{
handleSHIFTSelect(list);
}
else if (isCtrlDown) // handle CTRL - select second
{
handleCTRLSelect(list);
}
else // handle single clicking, it's normal way in using
{
handleSingleClick(list);
}
}
// method to handle SHIFT - select
private function handleSHIFTSelect(list:List):void
{
// when handle the SHIFT - select, get end item ( second selection of range ) first
endItem.setValue(list.id, list.selectedIndex);
cleanSelection(list);
// No matter select the range in UP-DOWN way or DOWN-UP way, here, change the select style to UP-DOWN
var usedInToEndMethod:int=parseNameToID(startItem.list ID) parseNameToID(endItem.listID) ? startItem.itemIndex : endItem.itemIndex;
// when user selects a range in same list
if (startItem.listID == endItem.listID)
{
var start:int=usedInToEndMethod usedInFromStartMethod ? usedInToEndMethod : usedInFromStartMethod;
selectItemFromTo(list, start, end);
}
// when user selects a range between list 1 and list 2
else if ((startItem.listID == LIST1 && endItem.listID == LIST2) || (startItem.listID == LIST2 && endItem.listID == LIST1))
{
selectFromStart(list2, usedInFromStartMethod);
selectToEnd(list1, usedInToEndMethod);
}
// when user selects a range between list 1 and list 2
else if ((startItem.listID == LIST1 && endItem.listID == LIST3) || (startItem.listID == LIST3 && endItem.listID == LIST1))
{
selectFromStart(list3, usedInFromStartMethod);
selectAllItem(list2);
selectToEnd(list1, usedInToEndMethod);
}
// when user selects a range between list 2 and list 3
else if ((startItem.listID == LIST2 && endItem.listID == LIST3) || (startItem.listID == LIST3 && endItem.listID == LIST2))
{
selectFromStart(list3, usedInFromStartMethod);
selectToEnd(list2, usedInToEndMethod);
}
else
{
// If you have other lists, terrible, try to handle all cases user selects a range from one list to another one... *_*
// So, this is not a good Demo, but anyway, it works~ ^_^
}
}
// used to get list index from a string, actually, if your list is not named in a indexable (XXX1, XXX2 ...) style
// you may need to find a way to make sure which list is first, which one is second and so on.
private function parseNameToID(value:String):Number
{
return Number(value.replace(LIST, ""));
}
// method to handle CTRL - select
private function handleCTRLSelect(list:List):void
{
// do nothing, List will support CTRL - select by default
// but need to set the start item ( first selection of range ), for the using in SHIFT - select
startItem.setValue(list.id, list.selectedIndex);
}
// method to handle single click on list
private function handleSingleClick(list:List):void
{
startItem.clean();
endItem.clean(); // clean end item to make sure all other lists will be cleaned in following method
cleanSelection(list, true);
// set the start item ( first selection of range ), for the using in SHIFT - select
startItem.setValue(list.id, list.selectedIndex);
}
// handle key down
protected override function keyDownHandler(event:KeyboardEvent):void
{
if (!valueSetFlag) // just set the value once when key down, actually, could be removed, this flag
{
isCtrlDown=event.ctrlKey;
isShiftDown=event.shiftKey;
valueSetFlag=true;
}
}
// handle key up
protected override function keyUpHandler(event:KeyboardEvent):void
{
if (valueSetFlag)
{
isCtrlDown=event.ctrlKey;
isShiftDown=event.shiftKey;
valueSetFlag=false;
}
}
]]>
List 1 - Item 1
List 1 - Item 2
List 1 - Item 3
List 1 - Item 4
List 1 - Item 5
List 1 - Item 6
List 1 - Item 7
List 2 - Item 1
List 2 - Item 2
List 2 - Item 3
List 2 - Item 4
List 2 - Item 5
List 2 - Item 6
List 2 - Item 7
List 3 - Item 1
List 3 - Item 2
List 3 - Item 3
List 3 - Item 4
List 3 - Item 5
List 3 - Item 6
List 3 - Item 7