[feather]StarlingUi框架——组件库及渲染器

       feather使用组件库,就不得不了解渲染器。查了一下资料Java的AWT也是有渲染器这类东西的!feather虽然带了默认皮肤,其实feather的每一个组件都没有皮肤,即使我们看到的那个皮肤,也是定制好的通过一定规则绘制出来的。所以要想要自己的一套UI风格就不得不了解渲染器的使用。

       但是很坑的是,官方并没有给出feather渲染器的demo,所以官网上提供的两种更改渲染器方法我只是调通了一种,另一种还不甚了解。并且自定义组件也只是大致给出了一个生命周期,我看了一个最简单的Label的源码,同样几个基本的渲染器是离不开的。所以望大神能指点一下渲染器的相关东东啊。

       组件的使用并不复杂,这里就以List为例了,直接贴代码反而更容易理解

public class ActivityMenu extends PanelScreen
{
    private var list:List;
        
    public function ActivityMenu()
    {
        super();
        this.addEventListener(FeathersEventType.INITIALIZE, initializeHandler);
    }
        
    private function initializeHandler(event:Event):void
    {
        this.removeEventListener(FeathersEventType.INITIALIZE,initializeHandler);
            
        list = new List();
        list.width = Constant.STAGE_WIDTH;
        list.height = Constant.STAGE_HEIGHT;
        //设置list的背景
         list.backgroundSkin = new Image(Root.mAssets.getTexture("BackgroundPic"));
        this.addChild(list);

        //制定列表元素数据
        var groceryList:ListCollection = new ListCollection(
        [
            {text:"价值120元代金券仅40元加2000积分"},
            {text:"1价值120元"},
            {text:"1价值120元"},
            {text:"1价值120元"},
            {text:"1价值120元"},
            {text:"1价值120元"},
            {text:"1价值120元"},
            {text:"1价值120元"},
            {text:"1价值120元"},
            {text:"1价值120元"},
        ]);
        
        //添加数据,并制定元素内容解析
        list.dataProvider = groceryList;
        list.itemRendererProperties.labelField = "text";
        
        var texture:Texture = Root.mAssets.getTexture("ItemBackgroundPic");
        var rect:Rectangle = new Rectangle(20,20,54,56);
        var textures:Scale9Textures = new Scale9Textures( texture, rect );
        //子渲染器背景样式
        list.itemRendererFactory = function():IListItemRenderer
        {
            //每一个子元素的渲染器,规则默认Button渲染器
            var renderer:DefaultListItemRenderer = new DefaultListItemRenderer();
            //背景,必须制定宽高,否则看不到添加的子元素背景
              renderer.width = Constant.STAGE_WIDTH*0.9;
            renderer.height = Constant.STAGE_HEIGHT*0.4;
            var image:Scale9Image = new Scale9Image( textures );
            renderer.defaultSkin = image;
            renderer.verticalAlign = "bottom";
            
             //定义字体样式
              renderer.labelFactory = function():ITextRenderer
            {
                var r:TextFieldTextRenderer = new TextFieldTextRenderer();                                                                       
                r.width = Constant.STAGE_WIDTH*0.9;
                r.height = Constant.STAGE_HEIGHT*0.1;
                r.wordWrap = true;
                r.textFormat = new TextFormat("",15,0xffffff,null,null,null,null,null,null,Constant.STAGE_HEIGHT*0.05);
                return r;
            }
                
            //添加字体背景
              var image1:Scale9Image = new Scale9Image( textures );
            image1.width = Constant.STAGE_WIDTH*0.9;
            image1.height = Constant.STAGE_HEIGHT*0.4/3.5;
            image1.y = renderer.height - image1.height;
            renderer.addChild(image1);//添加到renderer上面,猜测:可能基于Stage3D的,所以不会覆盖文字,矢量文字特殊        
            return renderer;
        }
                
        //子样式
         var layout:VerticalLayout = new VerticalLayout();
        layout.paddingTop = 10;
        layout.horizontalAlign = "center";
        layout.paddingBottom = 10;
        layout.gap = 10;
        list.layout = layout;
        
        //list添加监听
        list.addEventListener(Event.CHANGE,onListChangeHandler);
    }
    
    private function onListChangeHandler(e:Event):void
    {
        //输出选择顺序
        const selectedIndices:Vector.<int> = list.selectedIndices;
        trace("List onChange:", selectedIndices.length > 0 ? selectedIndices :this.list.selectedIndex);
        this.dispatchEventWith(Event.COMPLETE)
    }
}
看着上面的代码并不复杂,大部分的代码还是比较重复的这里我们共计用到了两个渲染类
DefaultListItemRenderer,TextFieldTextRenderer
并且在此有两个渲染函数,这是没个组件基本都有的,向List默认用的是Button的,所以List的默认渲染器里面肯定又Label所以就肯定有了我们labelFactory。
这样加入我们在使用一个组件的时候,我们只需要调用他的渲染器函数,通过上面的内部函数的方式设置渲染器的属性即可。
例如:list.itemRendererFactory = function():IListItemRenderer {……}
List使用注意:
1、itemRendererFactory这个函数其实就相当于一个遍历循环,你List指定多少就循环多少次渲染。也就是List的item渲染器,渲染器用的Button的,所以为了考虑效率问题尽量内部
不要创建过多的自定义变量,减少开销!
2、上面的代码使用到了Scale9Image,官网给的教程很详细,在此就不献丑了。
3、layout属性,正因为有这个属性我才这么坚持研究feather,因为布局很重要。List的layout设置的布局其实是对内部元素item的影响,其他组件也都有layout属性,也均是对内部添
加元素的影响。应多使用layout布局,并且feather有一个包里面有各种各样的layout为我们布局提供了方便,不用还像原来那样算过来算过去了的。
 
现在感觉feather搭了Starling的顺风车,通过stage3D加速的UI方法,如果真要是来做开发,感觉还是差一层封装啊,如果能像android那样,xml来写界面,可以外部引入style文件,
然后通过feather来内部解析xml,渲染就行了,这样能减少很多冗余代码的操作,也能使得层级关系更加的明朗!还有助于工作流脱离
 
posted @ 2013-11-12 20:55  河豚  阅读(565)  评论(0编辑  收藏  举报