Flex中,跨List实现SHIFT多选的例子
来源:互联网 发布:淘宝买六味地黄丸 编辑:程序博客网 时间:2024/06/14 00:35
方法其实很简单,就是自己写代码判断用户选的开始的位置和结束的位置,然后把中间的都选中就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
===========
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
minWidth="955"
creationComplete="init(event)"
fontFamily="Verdana"
minHeight="600">
<fx:Script>
<![CDATA[
import mx.core.FlexGlobals;
import mx.events.FlexEvent;
import spark.events.IndexChangeEvent;
// avoid hard code, always use const value is a good habit
private const LIST:String="list";
private const LIST1:String="list1";
private const LIST2:String="list2";
private const LIST3:String="list3";
private var isCtrlDown:Boolean=false; // used to save the status of Ctrl key
private var isShiftDown:Boolean=false; // used to save the status of Shift key
private var valueSetFlag:Boolean=false; // used to mark wether key down or key up value set to isCtrlDown and isShiftDown already.
private var startItem:SelectItemVO=new SelectItemVO(); // used to save the start selected item, for SHIFT - select
private var endItem:SelectItemVO=new SelectItemVO(); // used to save the end selected item, for SHIFT - select
// initialization
protected function init(event:FlexEvent):void
{
// add global listener to handle key down / key up for CTRL and SHIFT
FlexGlobals.topLevelApplication.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
FlexGlobals.topLevelApplication.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
// add listener to lists for CTRL+A event handling
list1.addEventListener(Event.SELECT_ALL, selectAll);
list2.addEventListener(Event.SELECT_ALL, selectAll);
list3.addEventListener(Event.SELECT_ALL, selectAll);
}
// method to set list selection from start to end
private function selectItemFromTo(list:List, start:int, end:int):void
{
var selectList:Vector.<int>=new Vector.<int>();
for (var i:int=start; i < end; i++)
{
selectList.push(i);
}
list.selectedIndices=selectList;
}
// method to set list selection from start to a specified index
private function selectFromStart(list:List, index:int):void
{
// here, add one because the array is from 0
// we need to add one to make sure the for-loop will run enough times to select the item you clicked
selectItemFromTo(list, 0, index + 1);
}
// method to set list selection from a specified index to end
private function selectToEnd(list:List, index:int):void
{
selectItemFromTo(list, index, list.dataProvider.length);
}
// method used to handle CTRL+A
private function selectAll(event:Event):void
{
selectAllItem(list1);
selectAllItem(list2);
selectAllItem(list3);
}
// method set all items selected for a list
private function selectAllItem(list:List):void
{
selectItemFromTo(list, 0, list.dataProvider.length);
}
// 1. when single click, clean other lists
// 2. when SHIFT - select, clean other lists which will not in the selection range
private function cleanSelection(list:List, doAll:Boolean=false):void
{
switch (list.id)
{
case LIST1:
if (doAll)
{
list2.selectedIndex=-1;
list3.selectedIndex=-1;
}
if (doAll || (startItem.listID != LIST2 && endItem.listID != LIST2))
list2.selectedIndices=new Vector.<int>();
if (doAll || (startItem.listID != LIST3 && endItem.listID != LIST3))
list3.selectedIndices=new Vector.<int>();
break;
case LIST2:
if (doAll)
{
list1.selectedIndex=-1;
list3.selectedIndex=-1;
}
if (doAll || (startItem.listID != LIST1 && endItem.listID != LIST1))
list1.selectedIndices=new Vector.<int>();
if (doAll || (startItem.listID != LIST3 && endItem.listID != LIST3))
list3.selectedIndices=new Vector.<int>();
break;
case LIST3:
if (doAll)
{
list1.selectedIndex=-1;
list2.selectedIndex=-1;
}
if (doAll || (startItem.listID != LIST1 && endItem.listID != LIST1))
list1.selectedIndices=new Vector.<int>();
if (doAll || (startItem.listID != LIST2 && endItem.listID != LIST2))
list2.selectedIndices=new Vector.<int>();
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.listID) <= parseNameToID(endItem.listID) ? startItem.itemIndex : endItem.itemIndex;
var usedInFromStartMethod:int=parseNameToID(startItem.listID) > 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;
var end: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;
}
}
]]>
</fx:Script>
<s:VGroup width="80%"
height="100%"
horizontalCenter="0"
verticalCenter="0"
horizontalAlign="center"
verticalAlign="middle">
<s:Label text="List 1"
fontSize="16"
fontWeight="bold"
width="70%"/>
<s:List id="list1"
width="70%"
allowMultipleSelection="true"
contentBackgroundColor="#72D9F7"
contentBackgroundAlpha="0.75"
changing="changingHandler(event)"
rollOverColor="#F5F184"
selectionColor="#F75854">
<s:dataProvider>
<s:ArrayCollection>
<fx:String>List 1 - Item 1</fx:String>
<fx:String>List 1 - Item 2</fx:String>
<fx:String>List 1 - Item 3</fx:String>
<fx:String>List 1 - Item 4</fx:String>
<fx:String>List 1 - Item 5</fx:String>
<fx:String>List 1 - Item 6</fx:String>
<fx:String>List 1 - Item 7</fx:String>
</s:ArrayCollection>
</s:dataProvider>
</s:List>
<s:Label text="List 2"
fontSize="16"
fontWeight="bold"
width="70%"/>
<s:List id="list2"
width="70%"
allowMultipleSelection="true"
contentBackgroundColor="#72D9F7"
contentBackgroundAlpha="0.75"
changing="changingHandler(event)"
rollOverColor="#F5F184"
selectionColor="#F75854">
<s:dataProvider>
<s:ArrayCollection>
<fx:String>List 2 - Item 1</fx:String>
<fx:String>List 2 - Item 2</fx:String>
<fx:String>List 2 - Item 3</fx:String>
<fx:String>List 2 - Item 4</fx:String>
<fx:String>List 2 - Item 5</fx:String>
<fx:String>List 2 - Item 6</fx:String>
<fx:String>List 2 - Item 7</fx:String>
</s:ArrayCollection>
</s:dataProvider>
</s:List>
<s:Label text="List 3"
fontSize="16"
fontWeight="bold"
width="70%"/>
<s:List id="list3"
width="70%"
allowMultipleSelection="true"
contentBackgroundColor="#72D9F7"
contentBackgroundAlpha="0.75"
changing="changingHandler(event)"
rollOverColor="#F5F184"
selectionColor="#F75854">
<s:dataProvider>
<s:ArrayCollection>
<fx:String>List 3 - Item 1</fx:String>
<fx:String>List 3 - Item 2</fx:String>
<fx:String>List 3 - Item 3</fx:String>
<fx:String>List 3 - Item 4</fx:String>
<fx:String>List 3 - Item 5</fx:String>
<fx:String>List 3 - Item 6</fx:String>
<fx:String>List 3 - Item 7</fx:String>
</s:ArrayCollection>
</s:dataProvider>
</s:List>
</s:VGroup>
</s:Application>
- Flex中,跨List实现SHIFT多选的例子
- Flex中如何自定义CheckBox作为List数据提供源的例子| 中文Flex例子
- Flex中如何通过addChild()函数在List中显示一个Sprite的例子
- Flex List 中实现插入图片、多行文本等
- FLEX中实现动态样式切换例子
- (java)关于List中对象实现Comparable接口的例子
- Flex中List实现上移下移功能
- Flex中List实现上移下移功能
- shift算法的实现
- Flex 4 List itemClick的实现
- Flex中利用 mx:States的例子
- Flex中button按钮的例子
- Flex中使用模块Module的例子
- 在装了FLEX builder插件的Eclipse中 ctrl+shift+R没反映的处理
- Flex中DataGrid多表头的实现
- Flex中DataGrid多表头的实现
- Flex中List数据源的配置
- 在装了FLEX builder插件的Eclipse中 ctrl+shift+R没反映
- 在FlashBuilder 4中增加对HTML XML Javascript的编辑器
- 简单的卡拉OK文字流动,定时器设置
- nginx的proxy配置(反向代理)
- mysql
- Android: 自定义窗口大小
- Flex中,跨List实现SHIFT多选的例子
- Flex中的set啊Flex中的set
- 算出大于一串数字的最小值,要求此数值的相邻两位不能相同
- 分享我做的截屏小工具
- 怎么把PPT转成EXE格式,详细步骤
- 怎么用C++生成WORD文档,详细步骤 - (参考基础上原创)
- nginx proxy https
- C#利用CER证书文件对远程Service进行验证
- NSIS脚本,检查权限和.NET环境 - (摘录及原创)