为Popuplist的下拉选项添加删除功能(NGUI)

NGUI例子里的popuplist是这样的:,但有时我们希望下拉选项都有删除功能,也就是这样:,一种方法是改popuplist的源码,我想这个实现起来不难,但现在我想说的是用反射来实现此功能,以及其他注意点。

第一步:我们查看下popuplist的源码可以发现,他有个OnCLick点击事件,而里面实现的就是绘制所有下拉选项的,并且所有下拉选项的的父节点都是mChild这个私有字段,

第二步:我们只要给popuplist再附加一个我们自己写的脚本A,在这个脚本里面通过反射mChild的孩子,就可以找到所有的下拉选项了,我们知道,一个对象如果给他附加多个脚本,并且每个脚本里面都有OnClick事件的话,那么所有脚本的OnCLick事件都会被执行的!但是,这有个特别需要注意的地方,就是他们执行的顺序,脚本在Inspector面板中越靠上就越先执行,所以我们为popuplist附加的脚本必须在UIPopup List之后,如果不在此之后的话,那么就会去先执行我们定义的脚本(这里我定义的脚本名称为Mypopuplist),可我们脚本里面是对mChild的反射,这时是反射不到结果的,因为UIPopup List里面的mChild还没实例化好,所以必然为空,所以popuplist对象的组件顺序必须是这样的,UIPopup List先去实例化好下拉选项,Mypopuplist再去反射下拉选项:

第三步:反射到所有的下拉选项之后,也就是UILbael对象,就为每一个UILabel对象添加删除Sprite即可,并为其添加点击事件,Mypopuplist中的OnClick事件代码如下(动态添加删除功能):

 1  void OnClick()
 2     {
 3         GameObject obj = GetChildren(popuplist, "mChild") as GameObject;
 4         if (obj != null)
 5         {
 6             UILabel[] labels = obj.GetComponentsInChildren<UILabel>();
 7             callBackData(labels);
 8         }
 9     }
10     //反射popuplist下拉选项中所有的孩子UILabel
11     object GetChildren(object obj, string name)
12     {
13         Type type = obj.GetType();
14         FieldInfo fieldinfo = type.GetField(name, BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
15         return fieldinfo.GetValue(obj);
16     }
17     //动态为每一个选项添加删除sprite
18     void callBackData(UILabel[] labels)
19     {
20         float f = -0.038f;
21         foreach (UILabel label in labels)
22         {
23             f = f - 0.01f;
24             UISprite sprite = NGUITools.AddSprite(label.gameObject, atlas, "chahao");
25             sprite.depth = label.depth + 1;
26             sprite.transform.localScale = new Vector3(0.25f, 0.25f, 0);
27             sprite.transform.Translate(0.42f, -0.03f, 0);
28             BoxCollider collider = sprite.gameObject.AddComponent<BoxCollider>();
29             collider.size = new Vector3(100f, 100f, 0);
30             UIEventListener listener = sprite.gameObject.AddComponent<UIEventListener>();
31             listener.onPress += (a, b) =>
32             {
33                 UILabel current = a.GetComponentInParent<UILabel>();
34                 DeleteItems(current.text);
35             };
36         }
37     }
38     //删除选项
39     public void DeleteItems(string username)
40     {
41         popuplist.items.Remove(username);
42     }

我想代码大家都能看懂,但我这里只说一点,这里我为什么给删除Sprite添加的是OnPress事件,而不是OnClick事件呢?因为OnClick事件是永远也不会被执行的,原因是这样的:我的NGUI版本是3.6.7,在UICamera脚本中的ProcessTouch方法里面,在判断是否要执行OnClick事件的判断语句:if (currentTouch.clickNotification != ClickNotification.None && currentTouch.pressed == currentTouch.current),而3.6.7之前或更早的版本里面的这句是这样写的:if (currentTouch.clickNotification != ClickNotification.None),第一个判断currentTouch.clickNotification != ClickNotification.None表示触摸事件是否在最后发出点击通知,只有当我们点击的对象是disabled的,或者拖动对象直到满足取消点击事件这个条件,ClickNotification枚举才为None,第二个判断是:点击的对象和当前鼠标碰到的对象是否是同一对象(因为有可能我们点击一个对象时,鼠标不释放,鼠标移动到另一个对象上去释放),如果我们此时用的NGUI版本里的UICamera,他里面对OnClick事件是否触发的判断只有这句:currentTouch.clickNotification != ClickNotification.None,那么这时我们用OnClick,是完全没有问题的!而如果用的是3.6.7版本的话,那么用OnClick是错误的,因为永远无法触发OnClick事件,因为当我们点击popuplist对象时,下拉选项被展现,此时我们再次点击(任何一个地方),下拉选项会被立即Destory销毁,也就是造成下拉选项被收缩的效果,这里也不得不说说OnClick事件和OnPress事件的作用了,OnClick事件是:当点击的对象和释放时的对象一致时,才触发OnClick事件,而这里下拉选项是被立即销毁的,所以当我们点击删除按钮并释放的时候,下拉选项在这之前就已经被销毁了,那么释放的对象和点击的对象就不一致了,也就自然而然形成不了OnClick 事件,而OnPress(obj,bool)事件,是当点击对象的时候就触发了,所以用OnPress是肯定能执行我们的删除功能的!

效果图如下:

以上是个人的总结,如有不当,希望大家多多批评指正!

时间: 2024-11-19 18:11:11

为Popuplist的下拉选项添加删除功能(NGUI)的相关文章

JS为Select下拉框添加输入功能

JavaScript使用parentNode.nextSibling.value实现的本功能,实际上你会发现网页上有两个控件元素,一个是Select,一个是input,使用CSS将input覆盖于select之上,再使用JS将下拉框的值赋值给input,实际上是用input模拟出了select的功能,思路非常新颖,也不知究竟有多少人须要select可输入文字的功能,以下是具体的实现代码:前端资源分享 .代码   <div style="position:relative;">

easyUI中select下拉框添加option选项

使用jquery easyui的下拉列表combobox碰上问题,下拉列表的项都是从 数据库读出来的,然后我想在动态生成的项中添加一项:"<option value=''>=全部=</option>". 但怎么也添加不成功. 首先试了直接用jquery对该下拉列表进行添加操作: JavaScript code ? 1 2 3 4 5 6 7 8 $('#selUnin').combobox({         url: _callback_url + '&

Android ActionBar下拉选项

package com.example.actionBarTest.actionBarList; import android.app.ActionBar; import android.app.Activity; import android.app.Fragment; import android.os.Bundle; import android.widget.ArrayAdapter; import android.widget.SpinnerAdapter; import com.ex

JavaScript---网络编程(11)--DHTML技术演示(4)-单选框/下拉菜单/添加文件

本节讲述单选框/下拉菜单/添加文件,综合css,html和JavaScript. 单选框: 实现的功能是:(类似平时的性格测试) 先隐藏一部分页面,然后通过点击单选框来显示. 再通过选项的选择-(每个选项有不同的积分)积分的多少来给出评语 演示代码: <html> <head> <title>DHTML技术演示---radio的使用</title> <meta http-equiv="content-Type" content=&q

Easyui Datagrid 的Combobox 如何动态修改下拉选项,以及值的转换

我是先将下拉选项的值通过datagrid的url查出来了,在每一行的row中 //项目结果选项卡的列表 $('#project_table').datagrid({ width : '100%', height: '378', url : 'getSeparationProjectInf', //title : '待分发条码列表', striped : true, nowrap : true, rownumbers : true, singleSelect : false, showHeader

WeChat-SmallProgram:自定义select下拉选项框组件

1):创建组件所需的文件 2):自定义组件 CSS 及 JS 组件的wxml: <view class='com-selectBox'> <view class='com-sContent' bindtap='selectToggle'> <view class='com-sTxt'>{{nowText}}</view> <image src='../../public/img/local/down.png' class='com-sImg' anim

js下拉选项框

功能实现:在js下拉选项框中不能出现属于自己的选项 在js文件中首先运行function函数 var dep = ["自己的选项","别人的选项"] 在function函数中动态的为#other下拉选项框添加option选项 $(function(){  var roomid = $("#roomId").val(); //所属部门 将部门名字添加到html页面 //通过#roomOwnerDeptId的值获取html中的自己的选项值 var s

Excel的单元格设置下拉选项并填充颜色

如何在Excel的单元格中加入下拉选项 方法/步骤   第一步:打开excel文档,选中需加入下拉选项的单元格.  第二步:点击菜单中的"数据"->"数据有效性"->"数据有效性".   第三步:在弹出的页面中设置菜单下,点击"允许"下选择"序列"按钮.   第四步:在来源中输入单元格中需设置的下拉选项,用英文的逗号","隔开,然后点击确定按钮. 即可得到我们要的效果. 怎么

下拉选项设置数据的三种方式介绍

度量快速开发平台中,在智能窗体上拖入下拉选择,可以实现很多功能.比如制作查询条件,选择数据等. 方法1:直接在下拉选择右边属性中设置数据. 使用效果: 该方法设置简答,对于那种是固定数据的设置,可以采用这样的效果实现.下拉选项1.Value   与 下拉选项1.SelectedText 获取的值都一样. 方法2:用下拉选项的SetItems方法实现 下拉选项1.SetItems("A,B,C,D",false) 效果与方法一一样,这个方法可以动态的来设置数据,比如根据不同的条件设置不同