读了好久源代码,才搞明白怎么回事,其实现在回过头来想想很简单,主要是寻找的过程艰难。
自定义一个control
在resources里面新建一个文件夹MyControls,新建一个名为my-nifty-drop-down-control.xml的文件。
<?xml version="1.0" encoding="UTF-8"?>
<nifty-controls xmlns="http://nifty-gui.lessvoid.com/nifty-gui">
<controlDefinition
style="my-nifty-drop-down-style"
name="my-dropDown"
controller="de.lessvoid.nifty.controls.dropdown.DropDownControl"
inputMapping="de.lessvoid.nifty.controls.dropdown.DropDownControlInputMapping"
viewConverterClass="com.happykai.crack3d.utils.MyDropDownViewConverter">
<panel style="#panel">
<interact onClick="dropDownClicked()"/>
<panel style="#panel-text">
<image id="#text" height="22px"/>
</panel>
<panel style="#panel-icon">
<image style="#icon"/>
</panel>
</panel>
</controlDefinition>
<popup id="dropDownBoxSelectPopup" style="my-nifty-drop-down-style" childLayout="absolute"
controller="de.lessvoid.nifty.controls.dropdown.DropDownPopup">
<interact onClick="close()"/>
<panel id="#panel" style="#list-panel" height="200px">
<control id="#listBox" name="my-listBox" horizontal="optional" displayItems="$displayItems"
selectionMode="Single" forceSelection="true"/>
</panel>
</popup>
<!-- DROP DOWN BOX POPUP (The Actual List this is) -->
</nifty-controls>
注意:<controlDefinition>里的name叫做name="my-dropDown",在其他xml里就把这个name当做control的名字。<controlDefinition>里一定要加viewConverterClass="com.happykai.demo.utils.MyDropDownViewConverter"
,引号中内容是重写的viewConverter类的名字
**原本的dropdown里panel里放的是text,如果是图片下拉框,就需要改成image,其他的布局自己照猫画虎在这个panel里定义就好"
在使用它的xml里添加引用
在要使用它的xml里加一句话,加载<nifty>标签的下一级就行,与screen平级。
<useControls filename="MyControls/my-nifty-drop-down-control.xml"/>
新建MyDropDownViewConverter.java
该类作用是实现了viewConverter类,在源码中有这样一句话
/**
* A simple implementation of DropDownViewConverter that will just use item.toString().
* This is the default DropDownViewConverter used when you don't set a different implementation.
*
* @param <T>
* @author void
public class SimpleDropDownViewConverter<T> implements DropDownViewConverter<T> {
...
}
*/
所以呢,要想自定义下拉列表,就需要实现这个类,照猫画虎就行。
public class MyDropDownViewConverter implements DropDown.DropDownViewConverter<NiftyImage> {
@Override
public void display(@Nonnull Element itemElement, @Nonnull NiftyImage item) {
ImageRenderer renderer = itemElement.getRenderer(ImageRenderer.class);
if (renderer == null) {
return;
}
renderer.setImage(item);
}
@Override
public int getWidth(@Nonnull Element itemElement, @Nonnull NiftyImage item) {
return 0;
}
}
调用
DropDown<NiftyImage> drop = screen.findNiftyControl(id, DropDown.class);
assert drop != null;
for (int i = 1; i <= Constants.TEXTURE_NUM; i++) {
NiftyImage image =
nifty.createImage(screen, "Textures/" + String.valueOf(i) + ".png", false);
drop.addItem(image);
}
drop.selectItemByIndex((dropNum - 1) % Constants.TEXTURE_NUM);
ok,到这里自定义的带图片下拉框就完成了。
但是存在内存泄漏的问题,这样的下拉框构建12个以上就会是opengl的内存溢出,因为明明是一样的下拉框,它却不会复用,一遍又一遍地把图片加到内存中,导致程序崩溃(默认的下拉框控件也是一样,会内存泄漏)。
该问题尚且未找到解决办法,如有同学解决还望告知,感谢分享。没解决前只能从交互上避免出现十几个下拉框的问题了。