Unity用UGUI制作一个多选下拉框
一、在Canvas下添加一个Dropdown
二、在Template中Item中添加Toggle,将Item中多余的部分删除,将Toggle的位置摆放正确 ,并且调整好大小。
三、代码部分(准备两个代码脚本)
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
public class MultiSelectDropdownTool : MonoBehaviour
{
public MyList<string> myValues = new MyList<string>();
[SerializeField]
private Dropdown multiSelectDropdown;
public List<string> lookValues = new List<string>();
public List<Toggle> multiSelectToggle = new List<Toggle>();
private async Task Start()
{
lookValues = myValues;
await Task.Delay(1);
multiSelectDropdown.captionText.text = "多选";
}
}
public class MyList<T> : List<T>
{
public UnityEvent<bool, T> myListChangedEvent = new UnityEvent<bool, T>();
public new void Add(T item)
{
base.Add(item);
myListChangedEvent?.Invoke(true, item);
}
public new void Remove(T item)
{
base.Remove(item);
myListChangedEvent?.Invoke(false, item);
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class MultiSelectDropdownToggleTool : MonoBehaviour
{
[SerializeField]
private MultiSelectDropdownTool multiSelectDropdownTool;
[SerializeField]
private Toggle multiSelectToggle;
[SerializeField]
private Dropdown multiSelectDropdown;
private static bool isNoTriggerValueChanged = false;
private void Start()
{
var label = multiSelectToggle.transform.Find("Label").GetComponent<Text>();
if(label.text.Equals("Toggle"))
return;
if (!multiSelectDropdownTool.multiSelectToggle.Contains(multiSelectToggle))
multiSelectDropdownTool.multiSelectToggle.Add(multiSelectToggle);
//找是否是有选择全部
if (label.text.Equals("选择全部"))
{
label.text = "选择全部";
multiSelectToggle.isOn = true;
for (int i = 1; i < multiSelectDropdown.options.Count; i++)
{
if(!multiSelectDropdownTool.myValues.Contains(multiSelectDropdown.options[i].text))
multiSelectToggle.isOn = false;
}
multiSelectToggle.onValueChanged.AddListener((value) =>
{
if (isNoTriggerValueChanged)
return;
foreach (var selectToggle in multiSelectDropdownTool.multiSelectToggle)
{
if (selectToggle.transform.Find("Label").GetComponent<Text>().text == "选择全部")
continue;
isNoTriggerValueChanged = true;
selectToggle.isOn = value;
isNoTriggerValueChanged = false;
}
});
return;
}
//不是第一个选择全部
multiSelectToggle.isOn = multiSelectDropdownTool.myValues.Contains(label.text);
multiSelectToggle.onValueChanged.AddListener((value) =>
{
var content = multiSelectToggle.transform.Find("Label").GetComponent<Text>().text;
if (value)
{
if (multiSelectDropdownTool.myValues.Contains(content))
return;
multiSelectDropdownTool.myValues.Add(content);
if (isNoTriggerValueChanged)
return;
Toggle selectAll = null;
foreach (var selectToggle in multiSelectDropdownTool.multiSelectToggle)
{
if (selectToggle.transform.Find("Label").GetComponent<Text>().text == "选择全部")
{
selectAll = selectToggle;
isNoTriggerValueChanged = true;
selectToggle.isOn = true;
isNoTriggerValueChanged = false;
}
else
{
if (selectToggle.isOn)
continue;
isNoTriggerValueChanged = true;
if (selectAll != null)
selectAll.isOn = false;
isNoTriggerValueChanged = false;
}
}
}
else
{
if (!multiSelectDropdownTool.myValues.Contains(content))
return;
multiSelectDropdownTool.myValues.Remove(content);
if (isNoTriggerValueChanged)
return;
foreach (var selectToggle in multiSelectDropdownTool.multiSelectToggle)
{
if (selectToggle.transform.Find("Label").GetComponent<Text>().text != "选择全部")
continue;
isNoTriggerValueChanged = true;
selectToggle.isOn = false;
isNoTriggerValueChanged = false;
}
}
});
}
private void OnDestroy()
{
if (multiSelectDropdownTool.multiSelectToggle.Contains(multiSelectToggle))
multiSelectDropdownTool.multiSelectToggle.Remove(multiSelectToggle);
}
}
四、挂载脚本
将Toggle中的Label拖入到Dropdown的ItemText框中
将MultiSelectDropdownTool脚本挂载到Dropdown上,将Dropdown拖入到MultiSelectDropdown框中。
将MultiSelectDropdownToggleTool脚本挂载到Toggle上,将Dropdown拖入到MultiSelectDropdownTool和MultiSelectDropdown框中;将Toggle拖入到MultiSelectToggle中。
五、开始运用
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class MultiSelectDropdownTest : MonoBehaviour
{
[SerializeField]
private Dropdown multiSelectDropdown;
private List<Dropdown.OptionData> multiSelectDropdownOptionData;
void Start()
{
multiSelectDropdownOptionData = new List<Dropdown.OptionData>
{
new Dropdown.OptionData("选择全部"),
new Dropdown.OptionData("第一个选择"),
new Dropdown.OptionData("第二个选择"),
new Dropdown.OptionData("第三个选择"),
new Dropdown.OptionData("第四个选择"),
new Dropdown.OptionData("第五个选择"),
};
multiSelectDropdown.options = multiSelectDropdownOptionData;
multiSelectDropdown.GetComponent<MultiSelectDropdownTool>().myValues.myListChangedEvent.AddListener((isAdd,value) =>
{
Debug.Log((isAdd ? "选择了:" : "取消选择:") + value);
});
}
}
将MultiSelectDropdownTest挂载到某个模型上,将MultiSelectDropdown挂载Dropdown,运行场景。(不想要选择全部的功能就直接不要加选择全部的字段)
随后和正常的Dropdown的使用方式一样,比如改变options的内容,但回调函数改变成:MultiSelectDropdownTool.myValues.myListChangedEvent.AddListener回调函数可执行选择改变的逻辑。