Flex ButtonBar 是怎么实现多个Button同时只选中一个
展开全部
一直以来不太明白: ButtonBar是怎么实现, 一组子ButtonBarButton中同一时刻是只能选中一个. 有时候自己写控件时也需要实现类似功能
先说我调查的思路吧.
第一步: 试验: MXML中直接在ButtonBar中写ButtonBarButton. 结果编译报错. 原因: ButtonBar是继承自SkinableDataContainer, DefaultProperty是dataProvider.
第二步: 试验: MXML中直接在Group中写ButtonBarButton. 结果实现不了只选一个的功能,证明这个功能肯定和ButtonBar有关.
第三步: 查看ButtonBar中到底是怎么生成ButtonBarButton的.
查看ButtonBarSkin皮肤可以知道 dataGroup(skinpart) 中加入的是ButtonBarButton
第四步: 继承关系:
ButtonBar extends ButtonBarBase
ButtonBarBase extends ListBase
ListBase extends SkinnableDataContainer
第五步: 看ButtonBarButton源文件,发现一个selected属性.
第六步: 在selected property setter方法中加入debug断点, 进行调试。然后在调试视图中看调用树。(这个方法一般人我不告诉他, 哈哈)
发现是ListBase类中的commitSelection函数有这样的语句:
var oldSelectedIndex:int = _selectedIndex;//将之前的selected ButtonBarButton的index保存为old
...
if (oldSelectedIndex != NO_SELECTION)
itemSelected(oldSelectedIndex, false); //是这个函数最终调用了老的已选中的ButtonBarButton的selected setter方法, 置为false
if (_selectedIndex != NO_SELECTION && _selectedIndex != CUSTOM_SELECTED_ITEM)
itemSelected(_selectedIndex, true); //调用了新的已候选的ButtonBarButton的selected setter方法, 置为true
...
当ButtonBarBase的partAdded函数中加入dataGroup时,为dataGroup增加element_added监听函数dataGroup_rendererAddHandler.
这个函数的实现:
private function dataGroup_rendererAddHandler(event:RendererExistenceEvent):void {
const renderer:IVisualElement = event.renderer; //renderer就是一个ButtonBarButton
if (renderer){
//在容器中(ButtonBar.dataGroup)监听所有子对象的CLICK事件
renderer.addEventListener(MouseEvent.CLICK, item_clickHandler);
...
}
}
这个函数为dataGroup的每个子Element attach了MouseEvent.CLICK的监听器, 这个监听器会将选中的item(ButtonBarButton)的itemIndex设置为ButtonBar.selectedIndex
简单总结: ButtonBar在每个ButtonBarButton加入的时候就开始监听它们的CLICK事件,好知道哪个Button被选中状态,在置当前的Button选中之前,通用调用之前的选中的那个Button的 selected setter方法将其设置为false. 做到将之前的设置为未选中。
先说我调查的思路吧.
第一步: 试验: MXML中直接在ButtonBar中写ButtonBarButton. 结果编译报错. 原因: ButtonBar是继承自SkinableDataContainer, DefaultProperty是dataProvider.
第二步: 试验: MXML中直接在Group中写ButtonBarButton. 结果实现不了只选一个的功能,证明这个功能肯定和ButtonBar有关.
第三步: 查看ButtonBar中到底是怎么生成ButtonBarButton的.
查看ButtonBarSkin皮肤可以知道 dataGroup(skinpart) 中加入的是ButtonBarButton
第四步: 继承关系:
ButtonBar extends ButtonBarBase
ButtonBarBase extends ListBase
ListBase extends SkinnableDataContainer
第五步: 看ButtonBarButton源文件,发现一个selected属性.
第六步: 在selected property setter方法中加入debug断点, 进行调试。然后在调试视图中看调用树。(这个方法一般人我不告诉他, 哈哈)
发现是ListBase类中的commitSelection函数有这样的语句:
var oldSelectedIndex:int = _selectedIndex;//将之前的selected ButtonBarButton的index保存为old
...
if (oldSelectedIndex != NO_SELECTION)
itemSelected(oldSelectedIndex, false); //是这个函数最终调用了老的已选中的ButtonBarButton的selected setter方法, 置为false
if (_selectedIndex != NO_SELECTION && _selectedIndex != CUSTOM_SELECTED_ITEM)
itemSelected(_selectedIndex, true); //调用了新的已候选的ButtonBarButton的selected setter方法, 置为true
...
当ButtonBarBase的partAdded函数中加入dataGroup时,为dataGroup增加element_added监听函数dataGroup_rendererAddHandler.
这个函数的实现:
private function dataGroup_rendererAddHandler(event:RendererExistenceEvent):void {
const renderer:IVisualElement = event.renderer; //renderer就是一个ButtonBarButton
if (renderer){
//在容器中(ButtonBar.dataGroup)监听所有子对象的CLICK事件
renderer.addEventListener(MouseEvent.CLICK, item_clickHandler);
...
}
}
这个函数为dataGroup的每个子Element attach了MouseEvent.CLICK的监听器, 这个监听器会将选中的item(ButtonBarButton)的itemIndex设置为ButtonBar.selectedIndex
简单总结: ButtonBar在每个ButtonBarButton加入的时候就开始监听它们的CLICK事件,好知道哪个Button被选中状态,在置当前的Button选中之前,通用调用之前的选中的那个Button的 selected setter方法将其设置为false. 做到将之前的设置为未选中。
2015-06-24
展开全部
你这问法,点击两次,可以进行判断,另外就是获取值,可以看一下例子,应该没有问题的!
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询