自定义UI组件 心得分享 (一) (List组件)

    说是自定义UI组建,其实更严格来说应该是自己写UI组建,因为这些组建都是常用的,比如Button,CheckBox,List等。

    为什么要自己写呢,用别人开源的类库不就好了?何必重复造轮子?关于这类问题,我是这样理解的,首先如果不自己动手写是不会对组件的内部结构了解的一清二楚的,二是效率问题,三是方便,比用别人的更方便?对,我就是这么认为的,你要说Cocos2dX的CCS组件怎么样?至少我是觉得还有很大提升空间的,个人觉得写的比较好的组件是Flex,确实有够牛,用起来很舒服,但是效率一直都是问题,不过也能优化吧,但是自己写的东西想怎么优化就怎么优化,不是更好?而且可以做自己的UI编辑器。

    Cocos2DX的点击事件做的如何?相信用过的人大部分都会觉得这是个坑。为什么,首先它没有跟显示对象关联起来,我明明设置了visible=false,确还可以点的到,明明显示对象都移除了还能点的到!实际应用中有这样的需求么? 真的是很麻烦的一件事,还有鼠标事件的层次跟显示对象的层次是分离的,明明在下面却可以先响应事件,这种设计有实际应用需求么?所以总得来说Cocos2DX坑还是挺多的,这种时候真的恨不得自己重新封装Cocos的显示列表。于是我也真的自己写了,包括CCS 组建,显示列表,事件机制,全部重写。

     好吧,回到主题上。今天想分享的组件是List,整套组建系统我真的重写了不下5次了,每次的应用场景都会稍微有点不同,而且每次都会写出新东西。

     List可以知道的是它的重点是显示里面的Item,什么叫Item?Item就是List的一行。当我们有大量数据的时候,当我们拖动List的时候,你是否会感觉效率比较低呢?嗯,我想大家或多或少都会遇到和感到这样的问题。

     我觉得比较好的做法是一个List框最多能显示多少个Item,最多就只创建多少个Item,比如一个List高100,一个Item高20,最多能显示5个,你有100条数据,初始化的时候有5个Item在显示之中,就只创建5个Item,然后当我们下拉的时候大部分的人是把里面的内容全部换一遍,但是实际是如果原来显示的内容是0~4条数据,往下拉了一段可以显示0~5了,这个时候是创建一个新的Item并把这个新的Item的值付为第5行数据,这样最省资源(CPU,内存)。当我们继续往下拉的时候能显示1~6了,这个时候只需要替换一个,就是0的内容替换成6,然后位置重新排一下,这样是最好的效果,但是即使是flex好像也没有做到这点,如果是自定的完全可以实现这个功能。

      以下贴一段List里面刷新内容的代码,供大家参考

		/**
		 *更新列表信息内容
		 * 
		 */		
		public function update():void
		{
			var start:int;
			var pos:int;
			//计算首个显示显示内容的index,_pos是当前记录的整体偏移量,也就是第一个显示对象的偏移量
			start = Math.floor((_posAdd==true?-1:1)*_pos/_itemHeight);
			pos = _pos + (_posAdd==true?1:-1)*start*_itemHeight;
			var len:int = _datas.length;
			var index:int = 0;
			var item:*;
			//记录哪些Item是在用的,并计算需要替换哪些Item的内容即可
			var useList:Vector.<CCSListItemBase> = this._items.slice(0,_items.length);
			var i:int;
			for(i = start; i < len; i++)
			{
				if(i < 0)
				{
					pos += (_posAdd==true?1:-1)*_itemHeight;
					continue;
				}
				for(var c:int = 0; c < useList.length; c++)
				{
					if(useList[c].data == _datas[i])
					{
						useList.splice(c,1);
						break;
					}
				}
				pos += (_posAdd==true?1:-1)*_itemHeight;
				if((_posAdd && pos >= (_vh==true?_height:_width)) || (!_posAdd  && pos <= -(_vh==true?_height:_width))) 
					break;
			}
			pos = _pos + (_posAdd==true?1:-1)*start*_itemHeight;
			//刷新和创建新的Item,只刷新必要的Item
			for(i = start; i < len; i++)
			{
				item = null;
				if(i < 0)
				{
					pos += (_posAdd==true?1:-1)*_itemHeight;
					continue;
				}
				if(_items.length)
				{
					for(var f:int = 0; f < _items.length; f++)
					{
						if((_items[f] as CCSListItemBase).data == _datas[i])
						{
							item = _items[f];
							break;
						}
					}
					if(item == null && useList.length)
					{
						item = useList.pop();
						item.setData(_datas[i]);
					}
				}
				if(item == null)
				{
					item = new _itemClass();
					_items.push(item);
					_cliper.addChild(item);
					item.setData(_datas[i]);
				}
				item.setVisible(true);
				if(_vh)
				{
					if(_posAdd == false) item.setY(pos - _itemHeight);
					else item.setY(pos);
				}
				else
				{
					if(_posAdd == false) item.setX(pos - _itemHeight);
					else item.setX(pos);
				}
				pos += (_posAdd==true?1:-1)*_itemHeight;
				index++;
				if((_posAdd && pos >= (_vh==true?_height:_width)) || (!_posAdd  && pos <= -(_vh==true?_height:_width))) 
					break;
			}
			//没有显示并且已经创建的Item设为不可见
			for(i = 0; i < useList.length; i++)
			{
				(useList[i] as DisplayObject).setVisible(false);
			}
		}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值