Unity用UGUI制作一个多选下拉框

Unity用UGUI制作一个多选下拉框

一、在Canvas下添加一个Dropdown

503ae060f3f247608bfda8fd2e68928c.png 62b58e252b3f453e8e444e4beab1e758.png

二、在Template中Item中添加Toggle,将Item中多余的部分删除,将Toggle的位置摆放正确 ,并且调整好大小。

 cf9c7456c5b845dfaef57cbe5a7ebcae.png400f83c2feec4ba7924b20850b1651b1.pngc9020071a5794690b5653dd7aa5fc51d.png

三、代码部分(准备两个代码脚本)

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);
    }
}

 四、挂载脚本

a691f97045ce4f5dab5787e173e04e10.png

将Toggle中的Label拖入到Dropdown的ItemText框中

1c7a2adef04e41bb996c07b9770a694d.png

将MultiSelectDropdownTool脚本挂载到Dropdown上,将Dropdown拖入到MultiSelectDropdown框中。

6994a0acf9d9462fa4e4265b9ac9db31.png

将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);
        });
    }
}

94c74c08e30840d9a15b23a155564c79.png

将MultiSelectDropdownTest挂载到某个模型上,将MultiSelectDropdown挂载Dropdown,运行场景。(不想要选择全部的功能就直接不要加选择全部的字段)

0bbf509390394f1f9b9f7dbfc344aaa9.png

4f3516efe3914a99bbcdaff9d35f4e65.png

随后和正常的Dropdown的使用方式一样,比如改变options的内容,但回调函数改变成MultiSelectDropdownTool.myValues.myListChangedEvent.AddListener回调函数可执行选择改变的逻辑。

猜你喜欢

转载自blog.csdn.net/weixin_48388330/article/details/135126028
今日推荐