Unity中的【Dropdown(包括TMP_Dropdown)下拉框当只有一个下拉值时多次点击 OnValueChange事件无效】的改进方法

Dropdown(包括TMP_Dropdown)下拉框当只有一个下拉值时,多次点击下拉框,并选择选项时, OnValueChange事件不响应

一、下拉框提供了一个【onValueChance】的事件接口

当下拉框值变化的时候,代表用户选择了新的值,于是执行对应逻辑

MyDropdown.onValueChanged.AddListener((idx) =>
        {
        		//响应用户选择的item逻辑    
        });

二、当下拉框只有一个item的时候,点选事件之后,选项值没有变化

Unity中的【Dropdown(包括TMP_Dropdown)下拉框当只有一个下拉值时多次点击 OnValueChange事件无效】的改进方法_第1张图片
在当前情形之下,用户onValueChanged事件无法响应,因为value没有改变,那么如何补救呢?

三、补救的方法

1、dropdown的工作原理

(1)如图【钻模】是一个dropdown,当用户没有点击它的时候,它的droplist是不显示的
Unity中的【Dropdown(包括TMP_Dropdown)下拉框当只有一个下拉值时多次点击 OnValueChange事件无效】的改进方法_第2张图片
(2)用户点击dropdown控件后,下拉框展开,实际上是动态生成下拉的item,如下所示:
Unity中的【Dropdown(包括TMP_Dropdown)下拉框当只有一个下拉值时多次点击 OnValueChange事件无效】的改进方法_第3张图片
(3)Dropdown List的构成如下所示:
每个展开的item,父节点都是一个Toggle,而且它的命名也很固定
[Item0:钻模],冒号前面是index,冒号后面选项的名字
Unity中的【Dropdown(包括TMP_Dropdown)下拉框当只有一个下拉值时多次点击 OnValueChange事件无效】的改进方法_第4张图片

2、拯救的方法

dropdown被点时,添加一下处理流程:

  • 【1】等下拉框展示
  • 【2】找到【Dropdown List】
  • 【3】找到【Dropdown List】下的【toggle】并绑定脚本
  • 【4】每个toggle绑定一个PointerClick事件:被点击时激发dropdown控件的onValueChanged事件

遵上所述,给dropdown控件(menuDropdown)添加以下代码:

/*
 *  ---- onValueChanged的bug ----
 *如果下拉框只有一个item,则value不能change,无法触发onValueChanged
 */

//用户点击下拉框中的toggle item时的事件处理
menuDropdown.GetComponent<EventTrigger>().AddListener(EventTriggerType.PointerClick,async (PointerEventData eventData) =>
    {
        //【1】下拉框展示
        Debug.Log("下拉框展示");
        await UniTask.DelayFrame(2); //等待2帧,让物体【Dropdown List】生成

        //【2】找到【Dropdown List】
        var droplist = menuDropdown.GetComponentsInChildren<Transform>(true)
            .First(x => x.name == "Dropdown List");

        Debug.Log($"物体Dropdown List = {droplist}");

        //【3】找到【Dropdown List】下的【toggle】并绑定脚本
        var toggles = droplist.GetComponentsInChildren<Toggle>(true);

        //【4】每个toggle绑定一个PointerClick事件:被点击时激发dropdown控件的onValueChanged事件
        foreach (var toggle in toggles)
        {
            Debug.Log(toggle.name);
            if (!toggle.GetComponent<EventTrigger>()) toggle.gameObject.AddComponent<EventTrigger>();
            toggle.gameObject.AddComponent<EventTrigger>().AddListener(EventTriggerType.PointerClick,
                async (PointerEventData eventData) =>
                {
                    Debug.Log($"点击的toggle为:{toggle.name}");
                    var idx = toggle.name.Split(":")[0].Replace("Item","");
                    Debug.Log($"点击的toggle 的 idx为:{idx}");

                    //** 如果只有一个下拉框,则主动触发一个onValueChanged事件 **
                    if (menuDropdown.options.Count == 1)
                    {
                        menuDropdown.onValueChanged.Invoke(int.Parse(idx));
                    }
                });
        }
    });

OnValueChange事件的绑定实现:

//用户选择
menuDropdown.onValueChanged.AddListener((idx) =>
{        
	//......  
});

你可能感兴趣的:(unity,游戏引擎,dropdown,onValueChange)