主要函数有 _horizontalLayout->setFocused(true);//设置焦点聚焦在该布局上
_horizontalLayout->setLoopFocus(true);//在该布局内循环设置焦点
_horizontalLayout->setFocusEnabled();//设置该控件上聚焦
_horizontalLayout->isFocusEnabled();//是否可以聚焦
这里说明几点特殊情况 VBox创建的布局,如果isLoopFocus(true);即可以在该布局例循环获取布局里控件的焦点,那么只能在垂直方向上循环获取焦点,在水平方向上不行。
同理如果是HBox创建的布局,且isLoopFocus(true);则只能在水平方向上获取焦点,垂直方向不可以。
如果isLoopFocus(false);则无论水平还是垂直,都不可以,循环获取焦点。
setScale设置的缩放是相对于自己的父类容器的,所以孙容器相对于爷爷容器类的缩放是子容器的缩放系数,乘以孙容器的缩放系数。
如果孙容器没缩放,而子容器缩放了0.5,则相当于孙容器缩放了1,最终相对于爷爷容器的缩放系数是0.5*1还是0.5.
Menu _dpadMenu = Menu::create(); //创建一个菜单
auto winSize = Director::getInstance()->getVisibleSize(); //获取窗口大小
auto leftItem = MenuItemFont::create("Left",CC_CALLBACK_0(UIFocusTestBase::onLeftKeyPressed,this)); //创建菜单项,设置菜单项获得焦点回调函数
_dpadMenu->addChild(leftItem);//加入菜单项到菜单中
//call this method to enable Dpad focus navigation
Widget::enableDpadNavigation(true);
cocos2d::EventListenerFocus _eventListener = EventListenerFocus::create();//新建事件监听器焦点
_eventListener->onFocusChanged = CC_CALLBACK_2(UIFocusTestBase::onFocusChanged,this);//给此焦点设置回调函数
_eventDispatcher->addEventListenerWithFixedPriority(_eventListener,1);//为特定的事件添加特定优先级的事件监听
//菜单项回调函数
void UIFocusTestBase::onLeftKeyPressed()
{
cocos2d::EventKeyboard::KeyCode cocos2dKey = EventKeyboard::KeyCode::KEY_DPAD_LEFT;//键盘事件值
cocos2d::EventKeyboard event(cocos2dKey,false);//根据此键盘事件值构造键盘事件
cocos2d::Director::getInstance()->getEventDispatcher()->dispatchEvent(&event);//事件调度器调度此事件
}
//焦点改变的回调函数
void UIFocusTestBase::onFocusChanged(cocos2d::ui::Widget * widgetLostFocus,cocos2d::ui::Widget * widgetGetFocus)
{
if (widgetGetFocus && widgetGetFocus->isFocusEnabled()){
widgetGetFocus->setColor(Color3B::RED); //得到焦点的设置为红色
}
if (widgetLostFocus && widgetLostFocus->isFocusEnabled())
{
widgetLostFocus->setCOlor(Color3B::WHITE);//失去焦点的设为白色
}
if (widgetLostFocus && widgetGetFocus)
{
CCLOG();
}
}
//水平布局测试
Layout *_horizontalLayout = HBox::create();
_horizontalLayout->setFocused(true);
_horizontalLayout->setLoopFocused(true);
int count = 3;
for (in i =0; i < count; ++i)
{
ImageView * w = ImageView::create("cocosui/scrollviewbg.png");
w->setTouchEnabled(true);
w->setTag(i);
w->addTouchEventListener(CC_CALLBACK_2(UIFocusTestHorizontal::onImageViewClicked,this));//添加图片事件回调处理
_horizontalLayout->addChild(w);
}
auto btn = Button::create("cocosui/switch-mask.png");
btn->addTouchEventListener(CC_CALLBACK_2(UIFocusTestHorizontal::toggleFocusLoop,this));//设置是否可以循环
//图片事件回调处理函数
void UIFocusTestBase::onImageViewClicked(cocos2d::Ref * ref,Widget::TouchEventType touchType)
{
if (touchType == Widget::TouchEventType::ENDED){
Widget * w = (Widget *)ref;
if (w->isFocusEnabled())//如果可以被聚焦,点击一下,设置为黄色,并且改为不能被聚焦
{
w->setFocusEnabled(false);
w->setColor(Color3B::YELLOW);
}else{ //如果不能被聚焦,点击一下,设置为白色,并且改为可以被聚焦
w->setFocusEnabled(true);
w->setColor(Color3B::WHITE);
}
}
void UIFocusTestHorizontal::toggleFocusLoop(cocos2d::Ref * pObjc,Widget::TouchEventType type)
{
if (type == WIdget::TouchEventType::ENDED)
{
_horizontalLayout->setLoopFocus(!_horizontalLayout->isLoopFocus()); //点击一下按钮,如果 isLoopFocus为true,则说明焦点只在layout内部循环,否则会跳出layout,如果 为false说明要跳出layout了,就不能再在layout内部循环了。
if (_horizontalLayout->isLoopFocus()){
_loopText->setString("loop enabled");
}else{
_loopText->setString("loop disabled");
}
}
}
//垂直布局测试
cocos2d::ui::Layout _verticalLayout = VBox::create();
int count = 3;
for (int i = 0; i < count; ++i)
{
ImageView * w = ImageView::create("cocosui/scrollviewbg.png");
w->setTouchEnabled(true);
w->addTouchEventListener(CC_CALLBACK_2(UIFocosTestVertical::onImageViewClicked,this));//设置图片事件回调函数
_verticalLayout->addChild(w);
if(i == 2){
w->requestFocus();//请求焦点
}
}
auto btn = Button::create("cocosui/switch-mask.png");btn->addTouchEventListener(CC_CALLBACK_2(UIFocosTestVertical::toggleFocusLoop,this));//这里是要处理整个布局的LoopFocus 即焦点是否仅仅在布局内部移动
这张Layout布局
主题是一个VBox,scale设为0.5,VBox里有一张图片,锚点为(0,0),图片的scaleX设为2.5,
里面添加了一个HBox,,scale设为0.8,加入到VBox中,并且添加两张图片,锚点为(1,0),scaleY设为2.0
HBox里再添加VBox,VBox中添加2张图片。
这张图片的布局,第一层是HBox,scale设为0.6,然后加入两张图片,图片锚点为(0, 1),scaleY设为2.4
加入VBox,VBox scale设为0.8,VBox添加两张图片,图片锚点为(0, 1),scaleX设为2.0,
LinearLayoutParameter *bottomParams = LinearLayoutParameter::create();
params->setMargin(Margin(0,50,0)); //参数 左,上,右,下 的顺序
firstVBox->setLayoutParameter(params);//控件设置边界参数,就是该控件与他相邻的控件边界相隔多远,layout之间似乎没有固定的大小,如果设置的边界距离值太小,有可能会重叠在一起。