panel是LAYA提供的一种滚动组件,LIST也可以滚动。
给panel直接添加子元素,发现panel的滚动区域有点大,最后一个子元素可以一直滑到panel中间,而策划想要的效果确实panel的最后一个子元素,滑到panel边缘就不要再滑动。
实现方法是在UI编辑器里面给panel添加一个子元素box,把原本需要添加到panel的元素添加到box,设置一个变量tempY记录box所有子元素的高度及间隙总和,每添加一个元素,tempY累加子元素的高和相邻元素间隙(最后一个子元素可以不加相邻元素间隙),最后设置box的高度为tempY即可实现panel最后一个子元素滑到边缘就停止滑动
//***************************************************分割线,下面是LAYA源码分析******************************************************
LAYA panel组件源码
Panel在创建时,会自动给panel添加一个_contentBox
/**@inheritDoc */
override protected function createChildren():void {
super.addChild(_content = new Box());
}
然后重写了一系列add和remove方法,重写成add和remove都是对panel的子元素_contentBox进行的add和remove
/**@inheritDoc */
override public function addChild(child:Node):Node {
child.on(Event.RESIZE, this, onResize);
_setScrollChanged();
return _content.addChild(child);
}
/**
* @private
* 子对象的 <code>Event.RESIZE</code> 事件侦听处理函数。
*/
private function onResize():void {
_setScrollChanged();
}
/**@inheritDoc */
override public function addChildAt(child:Node, index:int):Node {
child.on(Event.RESIZE, this, onResize);
_setScrollChanged();
return _content.addChildAt(child, index);
}
/**@inheritDoc */
override public function removeChild(child:Node):Node {
child.off(Event.RESIZE, this, onResize);
_setScrollChanged();
return _content.removeChild(child);
}
/**@inheritDoc */
override public function removeChildAt(index:int):Node {
getChildAt(index).off(Event.RESIZE, this, onResize);
_setScrollChanged();
return _content.removeChildAt(index);
}
/**@inheritDoc */
override public function removeChildren(beginIndex:int = 0, endIndex:int = 0x7fffffff):Node {
_content.removeChildren(beginIndex, endIndex);
_setScrollChanged();
return this;
}
/**@inheritDoc */
override public function getChildAt(index:int):Node {
return _content.getChildAt(index);
}
/**@inheritDoc */
override public function getChildByName(name:String):Node {
return _content.getChildByName(name);
}
/**@inheritDoc */
override public function getChildIndex(child:Node):int {
return _content.getChildIndex(child);
}
/**@inheritDoc */
override public function get numChildren():int {
return _content.numChildren;
}
所有实现panel滚动的时候,直接添加在panel中,相当于直接添加在_contentBox中,关系相当于panel-_contentBox-children;
而new一个box,添加到panel,然后再在new的box里面添加内容,关系相当于panel-_contentBox-new Box-children
panel通过设置并操作裁剪区域实现滚动效果,
设置裁剪
/**
* @private
* 设置内容的宽度、高度(以像素为单位)。
* @param width 宽度。
* @param height 高度。
*/
private function setContentSize(width:Number, height:Number):void {
var content:Box = _content;
content.width = width;
content.height = height;
content._style.scrollRect || (content.scrollRect = Rectangle.create());
content._style.scrollRect.setTo(0, 0, width, height);
content.scrollRect = content.scrollRect;
}
操作裁剪区域X或者Y(相当于设置起始填充坐标)
/**
* @private
* 滚动条的<code><code>Event.MOUSE_DOWN</code>事件侦听处理函数。</code>事件侦听处理函数。
* @param scrollBar 滚动条对象。
* @param e Event 对象。
*/
protected function onScrollBarChange(scrollBar:ScrollBar):void {
var rect:Rectangle = _content._style.scrollRect;
if (rect) {
var start:int = Math.round(scrollBar.value);
scrollBar.isVertical ? rect.y = start : rect.x = start;
_content.scrollRect = rect;
}
}
滑动时,实际上是改变了scrollRect的X或者Y