讀了好久源代碼,才搞明白怎么回事,其實現(xiàn)在回過頭來想想很簡單,主要是尋找的過程艱難。
自定義一個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
該類作用是實現(xiàn)了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> {
...
}
*/
所以呢,要想自定義下拉列表,就需要實現(xiàn)這個類,照貓畫虎就行。
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的內存溢出,因為明明是一樣的下拉框,它卻不會復用,一遍又一遍地把圖片加到內存中,導致程序崩潰(默認的下拉框控件也是一樣,會內存泄漏)。
該問題尚且未找到解決辦法,如有同學解決還望告知,感謝分享。沒解決前只能從交互上避免出現(xiàn)十幾個下拉框的問題了。