• NifytGUI——ListBox控件


      ListBox控件的用法,创建一个xml,代码如下:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <nifty xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://nifty-gui.lessvoid.com/nifty-gui" xsi:schemaLocation="https://raw.githubusercontent.com/void256/nifty-gui/1.4/nifty-core/src/main/resources/nifty.xsd https://raw.githubusercontent.com/void256/nifty-gui/1.4/nifty-core/src/main/resources/nifty.xsd">
        <useControls filename="nifty-default-controls.xml"/>
        <useStyles filename="nifty-default-styles.xml"/>
        <screen id="ListBoxScreen" controller="mygame.appState.ListBox01AppState">
            <layer id="ListBoxLayer" childLayout="absolute">
                <control name="listBox" id="myListBox" childLayout="overlay" horizontal="optional" width="612px" x="104" y="163" valign="center" vertical="optional" align="center" selectionMode="Single" displayItems="5" height="244px"/>
            </layer>
        </screen>
    </nifty>
    

      Java控制器,代码如下:

    /*
     * To change this license header, choose License Headers in Project Properties.
     * To change this template file, choose Tools | Templates
     * and open the template in the editor.
     */
    package mygame.appState;
    
    import com.jme3.app.Application;
    import com.jme3.app.SimpleApplication;
    import com.jme3.app.state.BaseAppState;
    import com.jme3.niftygui.NiftyJmeDisplay;
    import de.lessvoid.nifty.Nifty;
    import de.lessvoid.nifty.NiftyEventSubscriber;
    import de.lessvoid.nifty.controls.ListBox;
    import de.lessvoid.nifty.controls.ListBoxSelectionChangedEvent;
    import de.lessvoid.nifty.render.batch.BatchRenderConfiguration;
    import de.lessvoid.nifty.screen.Screen;
    import de.lessvoid.nifty.screen.ScreenController;
    import java.util.List;
    
    /**
     *
     * @author JhonKkk
     */
    public class ListBox01AppState extends BaseAppState implements ScreenController{
        private Nifty nifty;
        private NiftyJmeDisplay niftyDisplay;
        public class JustAnExampleModelClass {
            private String label;
    
            public JustAnExampleModelClass(final String label) {
              this.label = label;
            }
    
            public String toString() {
              return label; // we could really use anything in here, the name of the sword or something ;-)
            }
        }
        @Override
        protected void initialize(Application app) {
            SimpleApplication simpleApplication = (SimpleApplication) app;
            BatchRenderConfiguration config = new BatchRenderConfiguration();
            config.atlasWidth = 1024;
            config.atlasHeight = 1024;
            config.fillRemovedImagesInAtlas = false;
            config.disposeImagesBetweenScreens = false;
            config.useHighQualityTextures = true;
            niftyDisplay = NiftyJmeDisplay.newNiftyJmeDisplay(
                    simpleApplication.getAssetManager(),
                    simpleApplication.getInputManager(),
                    simpleApplication.getAudioRenderer(),
                    simpleApplication.getGuiViewPort(),config);
            nifty = niftyDisplay.getNifty();
            nifty.enableAutoScaling(800, 600);
            nifty.fromXml("Interface/ListBox01.xml", "ListBoxScreen", this);
            simpleApplication.getGuiViewPort().addProcessor(niftyDisplay);
        }
    
        @Override
        protected void cleanup(Application app) {
        }
    
        @Override
        protected void onEnable() {
        }
    
        @Override
        protected void onDisable() {
        }
    
        @Override
        public void bind(Nifty nifty, Screen screen) {
    //        ListBox listBox = screen.findNiftyControl("myListBox", ListBox.class);
    //        listBox.addItem("a");
    //        listBox.addItem("b");
    //        listBox.addItem("c");
            ListBox<JustAnExampleModelClass> listBox = (ListBox<JustAnExampleModelClass>) screen.findNiftyControl("myListBox", ListBox.class);
            listBox.addItem(new JustAnExampleModelClass("You can add more lines to this ListBox."));
            listBox.addItem(new JustAnExampleModelClass("Use the append button to do this."));
        }
        @NiftyEventSubscriber(id="myListBox")
        public void onMyListBoxSelectionChanged(final String id, final ListBoxSelectionChangedEvent<JustAnExampleModelClass> event) {
            List<JustAnExampleModelClass> selection = event.getSelection();
            for (JustAnExampleModelClass selectedItem : selection) {
                System.out.println("listbox selection [" + selectedItem.label + "]");
            }
        }
    
        @Override
        public void onStartScreen() {
        }
    
        @Override
        public void onEndScreen() {
        }
        
    }

      其中@NiftyEventSubscriber(id="myListBox")注解方法onMyListBoxSelectionChanged在每次listBox发生事件时回调,然后我们在方法里获取当前选择项并打印。

    注意,该注解并非监听onSelect或onCheck事件,而是监听事件发生。

      如图:

       如果需要改变ListBox的字体,需要通过修改ListBox的Style来实现,通过研读默认的Style,可以发现ListBox使用默认的NiftyLabel作为Item,而默认的NiftyLabel又使用了默认的字体。所以我们只需要改变ListBox的Style,甚至可以通过Style修改用其他控件作为ListBox的Item。

      默认的Style文件:

    <?xml version="1.0" encoding="UTF-8"?>
    <nifty-styles xmlns="http://nifty-gui.lessvoid.com/nifty-gui">
    
        <style id="nifty-listbox">
            <attributes/>
        </style>
        <style id="nifty-listbox#scrollpanel">
            <attributes focusable="true" padding="1px"/>
            <effect overlay="true">
                <onActive name="colorBar" color="#666f" post="false" neverStopRendering="true" timeType="infinite"/>
                <onActive name="border" border="1px" color="#222f" inset="1px,0px,0px,1px"/>
                <onFocus name="border" border="1px" color="#f006"/>
                <onEnabled name="renderQuad" startColor="#2228" endColor="#2220" post="false" length="150"/>
                <onDisabled name="renderQuad" startColor="#2220" endColor="#2228" post="false" length="150"/>
            </effect>
        </style>
        <style id="nifty-listbox#bottom-right">
            <attributes width="23px" height="23px"/>
        </style>
        <style id="nifty-listbox-item" base="nifty-label">
            <attributes color="#000f" width="100%" align="left" textVAlign="center" textHAlign="left"/>
            <interact onClick="listBoxItemClicked()"/>
            <effect>
                <onCustom customKey="focus" name="colorBar" post="false" color="#444f" neverStopRendering="true"
                          timeType="infinite"/>
                <onCustom customKey="select" name="colorBar" post="false" color="#444f" neverStopRendering="true"
                          timeType="infinite"/>
                <onCustom customKey="select" name="textColor" post="false" color="#fc0f" neverStopRendering="true"
                          timeType="infinite"/>
                <onHover name="colorBar" color="#444f" post="false" neverStopRendering="true" timeType="infinite"
                         inset="1px"/>
                <onClick name="focus" targetElement="#parent#parent"/>
            </effect>
        </style>
    </nifty-styles>

      其中<style id="nifty-listbox-item" base="nifty-label">表明了ListBox默认使用自带的NiftyLabel作为Item,而默认的NiftyLabel使用默认的字体。

      自定义Item

      通过研读默认的nifty-listbox.xml,我们会发现默认的ListBox的item是一个NiftyLabel。而我们在游戏开发中往往不仅仅局限于显示文本列表。更多的是复杂的图文列表。那么,NiftyGUI是否可以像Android一样,提供自定义List Item的接口呢?答案是肯定的。

      具体而言,我们需要了解ListBox如何渲染一个Item,通过Wiki和源码可以简单了解到,ListBox渲染一个Item需要先提供模板控制器,然后每次渲染时通过模板控制器去获取Item并适配相应数据,这个过程其实和Android的RecylerView差不多,在Android里面,使用RecylerView渲染自定义Item,通常,我们可以用一个独立的布局文件来作为Item的模板,然后在java代码里实现适配器,加载对应的布局item,并填充数据。在NiftyGUI里,也是类似的。

      第一步,添加一个自定Item,在NiftyGUI中,UI控件分为两大类,一类是NiftyElement(如Layer,Panel等),另一类就是具体的控件类型(如Button,Label等),所以,在NiftyGUI中,添加一个自定义控件,就是一个自定义Control。在SDK中,在Interface目录下创建一个control目录,然后右键新建一个名为ImgLabelItem的Item控制器,如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <nifty-controls xmlns="http://nifty-gui.lessvoid.com/nifty-gui">
        <controlDefinition style="img-label-listbox" name="img-label-item">
            <panel style="#panel" childLayout="horizontal" width="100%" align="center">
                <image id="#icon" width="23px" height="23px" />
                <control id="#text" name="label" align="left" style="img-label-listbox-label-item" textHAlign="left" height="23px" width="*" wrap="true" />
            </panel>
        </controlDefinition>
    </nifty-controls>

      分析下这里的代码,首先第一行<nifty-controls>标签定义这是一个nifty控制器(所有具体的ui控件都是一个控制器或element),这表明我们正在创建一个自定义nifity控件;接下来的<controlDefinition>表明我们的控件定义从这里开始,在controlDefinition标签中,有一个style属性,这个非常重要,我们引用自己定义的img-label-listbox样式,这在接下来介绍,接着name属性指定了这个控件的名称是img-label-item(为何不叫id呢?其实可以这样理解,id是一个具体的实例的标识符,而name表明这是一个类的名称),以便我们在布局文件中使用这种控件。

      接着,我们通过组合基础控件类panel,image,control完成了我们这个自定义控件的内容(panle,image和control这些是基础类型控件,复杂的自定义控件都是通过组合基础类型得到,就像复合数据类型是通过组合各种基础数据类型实现的道理一样)。

      panel提供了一个容器,使用id为#panel的样式(这个样式定义在默认的nifty中,你可能会不解,没看到哪里引入了这个样式文件,没错,这里没有引入其他样式文件,因为我们在最后的屏幕布局中才引入默认的nifty style,同样,上面的img-label-listbox是一个自定义样式的id,但是在这个xml中我们并没有看到任何引入样式文件的代码,因为我们统一在最后的屏幕布局中才引入),childLayout指定子对象使用水平布局,width指定为填充100%宽度,而algin指定了panel对齐中心于父控件。

      image提供了一个图标控件,id为#icon,width为23像素,height为23像素。

      control的name属性表明这个control是一个label-control控件,有一点需要注意,image和panel都是element类型的控件,所以直接用image或panel作为标签名;而label是一个control类型的控件,所以通过control并指定name属性来描述这种控件。style使用id为img-label-listbox-label-item的样式,其他属性不用多说都能理解是什么意思。

      自定义控件定义好了,接下来,创建我们的自定义控件的样式文件,如果不创建自定义样式文件,则不存在上面id为img-label-listbox和img-label-listbox-label-item的样式,则只能使用默认的样式(样式必须显式指定,否则渲染会黑屏,但由于复杂控件由基础控件组成,基础控件默认就指定了样式,所以可以忽略style属性,但是controlDefinition必须显式指定样式)。我们在Interface下创建一个styles文件夹,然后添加一个名为img-label-list.xml的空样式文件,如下:

       打开样式文件,我们找到默认的nifty的listbox样式文件,具体位置在如下位置:

      把里面的内容复制到我们新建的style中,然后进行修改,如下:

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <nifty-styles xmlns="http://nifty-gui.lessvoid.com/nifty-gui">
     3 
     4     <style id="img-label-listbox">
     5         <attributes/>
     6     </style>
     7     <style id="img-label-listbox#scrollpanel">
     8         <attributes focusable="true" padding="1px"/>
     9         <effect overlay="true">
    10             <onActive name="colorBar" color="#666f" post="false" neverStopRendering="true" timeType="infinite"/>
    11             <onActive name="border" border="1px" color="#222f" inset="1px,0px,0px,1px"/>
    12             <onFocus name="border" border="1px" color="#f006"/>
    13             <onEnabled name="renderQuad" startColor="#2228" endColor="#2220" post="false" length="150"/>
    14             <onDisabled name="renderQuad" startColor="#2220" endColor="#2228" post="false" length="150"/>
    15         </effect>
    16     </style>
    17     <style id="img-label-listbox#bottom-right">
    18         <attributes width="23px" height="23px"/>
    19     </style>
    20     <style id="img-label-listbox-label-item" base="nifty-label">
    21         <attributes color="#000f" width="100%" align="left" textVAlign="center" textHAlign="left"/>
    22         <interact onClick="listBoxItemClicked()"/>
    23         <effect>
    24             <onCustom customKey="focus" name="colorBar" post="false" color="#444f" neverStopRendering="true"
    25                       timeType="infinite"/>
    26             <onCustom customKey="select" name="colorBar" post="false" color="#444f" neverStopRendering="true"
    27                       timeType="infinite"/>
    28             <onCustom customKey="select" name="textColor" post="false" color="#fc0f" neverStopRendering="true"
    29                       timeType="infinite"/>
    30             <onHover name="colorBar" color="#444f" post="false" neverStopRendering="true" timeType="infinite"
    31                      inset="1px"/>
    32             <onClick name="focus" targetElement="#parent#parent"/>
    33         </effect>
    34     </style>
    35 </nifty-styles>

      在第4行定义了一个id为img-label-listbox的样式,但这是一个空样式;接着在第7行和第17行定义了img-label-listbox的伪类样式,这才是真正的img-label-listbox的各个项的样式;然后,在第20行定义了一个img-label-listbox#bottom-right样式,通过base属性表明该样式继承自nifty-label样式,说明这是一个为label控件类型定制的样式。我们看看这个样式定义,首先attributes定义了color,width,align等一些属性,然后通过interact标签定义了用户交互响应listBoxItemClicked()函数,这个是函数是默认的listbox控制器内部的函数,建议你直接用这个,因为你自己实现的话需要写适配器,绑定等一系列逻辑;接下来effect标签定义了控件的一些效果,比如鼠标悬浮时(onHover事件)的效果,或者点击时(onClick事件)的效果,另外,也可通过onCustom标签来描述事件,比如将onClick事件改为onCustom描述则是:<onCustom customKey="click"/>,所以,我们通过onCustom标签分别定义了focus事件,select事件发生时,哪些属性产生效果;如<onCustom customKey="focus" name="colorBar".../>定义了当focus事件发生时,属性colorBar产生特效效果,具体效果由后面的post,color,neverStopRendering等参数定义。

      现在,我们完成了自定义样式和自定义控件,可以实现我们的listBox的自定义item了,我们创建一个新的名为ImgLabelListBox01的gui文件,然后,代码如下:

     1 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
     2 <nifty xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://nifty-gui.lessvoid.com/nifty-gui" xsi:schemaLocation="https://raw.githubusercontent.com/void256/nifty-gui/1.4/nifty-core/src/main/resources/nifty.xsd https://raw.githubusercontent.com/void256/nifty-gui/1.4/nifty-core/src/main/resources/nifty.xsd">
     3     <useControls filename="nifty-default-controls.xml"/>
     4     <!--引入自定义控制器-->
     5     <useControls filename="Interface/control/ImgLabelItem.xml"/>
     6     <useStyles filename="nifty-default-styles.xml"/>
     7     <!--引入自定义样式-->
     8     <useStyles filename="Interface/styles/img-label-listbox.xml"/>
     9     <screen id="ListBoxScreen" controller="mygame.appState.ImgLabelItemListBoxAppState">
    10         <layer id="ListBoxLayer" childLayout="absolute">
    11             <control name="listBox" id="myListBox" childLayout="overlay" horizontal="optional" width="612px" x="104" y="163" valign="center" vertical="optional" align="center" selectionMode="Single" displayItems="5" height="244px" viewConverterClass="mygame.gui.ImgLabelConverter">
    12                 <control name="img-label-item" controller="de.lessvoid.nifty.controls.listbox.ListBoxItemController" />
    13             </control>
    14         </layer>
    15     </screen>
    16 </nifty>

      这里可以看到,我们在自定义控件中使用的样式(如id为img-listbox的样式),是包含在img-label-listbox.xml这个文件中,我们在gui文件中引入了这个样式文件,然后引入了自定义控制器文件ImgLabelItem.xml。这样,我们的gui文件就可以访问到自定义控件,同时可以访问我们的自定义样式了。

      在第11行这里,我们定义了一个id为myListBox的listBox控件,然后添加了一个viewConverterClass="mygame.gui.ImgLabelConverter"属性,这个是item数据适配器对象,是一个我们自定义的item适配器java类,等会我们会介绍;然后,我们在内部定义了一个control标签,这个标签的name属性表明,这个control是一个img-label-item类型的控件,也就是我们自定义的类型为img-label-item的控件。同时指定controller属性,这个值可以写死,它使用默认的控制器类处理控件交互。

      接下来实现名称为mygame.gui.ImgLabelConverter的类,代码如下:

     1 /*
     2  * To change this license header, choose License Headers in Project Properties.
     3  * To change this template file, choose Tools | Templates
     4  * and open the template in the editor.
     5  */
     6 package mygame.gui;
     7 
     8 import de.lessvoid.nifty.controls.ListBox;
     9 import de.lessvoid.nifty.elements.Element;
    10 import de.lessvoid.nifty.elements.render.ImageRenderer;
    11 import de.lessvoid.nifty.elements.render.TextRenderer;
    12 
    13 /**
    14  *
    15  * @author JhonKkk
    16  */
    17 public class ImgLabelConverter implements ListBox.ListBoxViewConverter<ImgLabel>{
    18     private static final String ICON = "#icon";
    19     private static final String TEXT = "#text";
    20 
    21     /**
    22      * Default constructor.
    23      */
    24     public ImgLabelConverter() {
    25     }
    26     
    27     /**
    28      * {@inheritDoc}
    29      */
    30     @Override
    31     public final void display(final Element listBoxItem, final ImgLabel item) {
    32         final Element text = listBoxItem.findElementById(TEXT);
    33         final TextRenderer textRenderer = text.getRenderer(TextRenderer.class);
    34         final Element icon = listBoxItem.findElementById(ICON);
    35         final ImageRenderer iconRenderer = icon.getRenderer(ImageRenderer.class);
    36         if (item != null) {
    37             textRenderer.setText(item.getLabel());
    38             iconRenderer.setImage(item.getIcon());
    39         } else {
    40             textRenderer.setText("");
    41             iconRenderer.setImage(null);
    42         }
    43     }
    44 
    45     /**
    46      * {@inheritDoc}
    47      */
    48     @Override
    49     public final int getWidth(final Element listBoxItem, final ImgLabel item) {
    50         final Element text = listBoxItem.findElementById(TEXT);
    51         final TextRenderer textRenderer = text.getRenderer(TextRenderer.class);
    52         final Element icon = listBoxItem.findElementById(ICON);
    53         final ImageRenderer iconRenderer = icon.getRenderer(ImageRenderer.class);
    54         return ((textRenderer.getFont() == null) ? 0 : textRenderer.getFont().getWidth(item.getLabel()))
    55                 + ((item.getIcon() == null) ? 0 : item.getIcon().getWidth());
    56     }
    57     
    58 }

      其中该类继承自ListBoxViewConverter类,这是item适配器父类,实现了两个方法display和getWidth。其中display在每个item被渲染时回调,在这里填入item的数据(就跟Android里的RecerverView适配器一样);在getWidth返回当前渲染的item的宽度,返回0不可见。

      其中ImgLabel是一个javaBean类,代码如下:

     1 /*
     2  * To change this license header, choose License Headers in Project Properties.
     3  * To change this template file, choose Tools | Templates
     4  * and open the template in the editor.
     5  */
     6 package mygame.gui;
     7 
     8 import de.lessvoid.nifty.render.NiftyImage;
     9 
    10 /**
    11  *
    12  * @author JhonKkk
    13  */
    14 public class ImgLabel {
    15     private String label;
    16     private NiftyImage icon;
    17 
    18     public ImgLabel(String label, NiftyImage icon) {
    19         this.label = label;
    20         this.icon = icon;
    21     }
    22 
    23     public NiftyImage getIcon() {
    24         return icon;
    25     }
    26 
    27     public String getLabel() {
    28         return label;
    29     }
    30     
    31 }

      这没啥好说的,就是包含一个label和icon的数据结构。接着,我们创建名为mygame.appState.ImgLabelItemListBoxAppState的gui屏幕控制器类,用于实现最终整合gui的逻辑。如下:

     1 /*
     2  * To change this license header, choose License Headers in Project Properties.
     3  * To change this template file, choose Tools | Templates
     4  * and open the template in the editor.
     5  */
     6 package mygame.appState;
     7 
     8 import com.jme3.app.Application;
     9 import com.jme3.app.SimpleApplication;
    10 import com.jme3.app.state.BaseAppState;
    11 import com.jme3.niftygui.NiftyJmeDisplay;
    12 import de.lessvoid.nifty.Nifty;
    13 import de.lessvoid.nifty.NiftyEventSubscriber;
    14 import de.lessvoid.nifty.controls.ListBox;
    15 import de.lessvoid.nifty.controls.ListBoxSelectionChangedEvent;
    16 import de.lessvoid.nifty.render.batch.BatchRenderConfiguration;
    17 import de.lessvoid.nifty.screen.Screen;
    18 import de.lessvoid.nifty.screen.ScreenController;
    19 import java.util.List;
    20 import mygame.gui.ImgLabel;
    21 
    22 /**
    23  *
    24  * @author JhonKkk
    25  */
    26 public class ImgLabelItemListBoxAppState extends BaseAppState implements ScreenController{
    27     private Nifty nifty;
    28     private NiftyJmeDisplay niftyDisplay;
    29     public class JustAnExampleModelClass {
    30         private String label;
    31 
    32         public JustAnExampleModelClass(final String label) {
    33           this.label = label;
    34         }
    35 
    36         public String toString() {
    37           return label; // we could really use anything in here, the name of the sword or something ;-)
    38         }
    39     }
    40     @Override
    41     protected void initialize(Application app) {
    42         SimpleApplication simpleApplication = (SimpleApplication) app;
    43         BatchRenderConfiguration config = new BatchRenderConfiguration();
    44         config.atlasWidth = 1024;
    45         config.atlasHeight = 1024;
    46         config.fillRemovedImagesInAtlas = false;
    47         config.disposeImagesBetweenScreens = false;
    48         config.useHighQualityTextures = true;
    49         niftyDisplay = NiftyJmeDisplay.newNiftyJmeDisplay(
    50                 simpleApplication.getAssetManager(),
    51                 simpleApplication.getInputManager(),
    52                 simpleApplication.getAudioRenderer(),
    53                 simpleApplication.getGuiViewPort(),config);
    54         nifty = niftyDisplay.getNifty();
    55         nifty.enableAutoScaling(800, 600);
    56         nifty.fromXml("Interface/ImgLabelListBox01.xml", "ListBoxScreen", this);
    57         simpleApplication.getGuiViewPort().addProcessor(niftyDisplay);
    58     }
    59 
    60     @Override
    61     protected void cleanup(Application app) {
    62     }
    63 
    64     @Override
    65     protected void onEnable() {
    66     }
    67 
    68     @Override
    69     protected void onDisable() {
    70     }
    71 
    72     @Override
    73     public void bind(Nifty nifty, Screen screen) {
    74         ListBox<ImgLabel> listBox = screen.findNiftyControl("myListBox", ListBox.class);
    75         listBox.addItem(new ImgLabel("Help", nifty.getRenderEngine().createImage(screen, "Interface/help.png", false)));
    76         listBox.addItem(new ImgLabel("Text", nifty.getRenderEngine().createImage(screen, "Interface/help.png", false)));
    77     }
    78     @NiftyEventSubscriber(id="myListBox")
    79     public void onMyListBoxSelectionChanged(final String id, final ListBoxSelectionChangedEvent<ImgLabel> event) {
    80         List<ImgLabel> selection = event.getSelection();
    81         for (ImgLabel selectedItem : selection) {
    82             System.out.println("listbox selection [" + selectedItem.getLabel() + "]");
    83         }
    84     }
    85 
    86     @Override
    87     public void onStartScreen() {
    88     }
    89 
    90     @Override
    91     public void onEndScreen() {
    92     }
    93     
    94 }

      在bind()函数中初始化数据项目,在onMyListBoxSelectionChanged()方法中,获取选中的item并打印。最终效果如下:

      很显然,这就是我们的自定义Item。

      总结,一个自定义Item的实现需要以下几个步骤:

      1.实现自定义控件布局

      2.实现自定义控件样式

      3.实现自定义控件Item适配器

      需要注意的一点,如果你的自定义Item无法选中,即无法获取选中事件,那么极有可能是你没有为Item定义样式并定义Effect效果,要是一个item能够被选中,必须包含select效果,在这个例子中,是这样的:

    1 <onCustom customKey="select" name="colorBar" post="false" color="#444f" neverStopRendering="true"
    2                       timeType="infinite"/>
    3             <onCustom customKey="select" name="textColor" post="false" color="#fc0f" neverStopRendering="true"
    4                       timeType="infinite"/>

      还有一点需要注意,我们仅仅为id为#text控件定义了select效果,所以点击#text控件会有效,但是点击id为#icon的控件仍然无效。

  • 相关阅读:
    kafka 流式计算
    解决山地车令人讨厌的中轴异响及其他异响问题
    go语言通道详解
    使用Spring Cloud连接不同服务
    并发之痛 Thread,Goroutine,Actor
    用go语言实现线程池
    golang go语言通道类型的通道示例 通道的通道
    Java 网络IO编程总结(BIO、NIO、AIO均含完整实例代码)
    spring5 reactive
    Go 语言和 Scala 语言对比
  • 原文地址:https://www.cnblogs.com/JhonKkk/p/14236917.html
Copyright © 2020-2023  润新知