Unity UGUI_DropDown控件模拟QQ分组的使用心得

Posted 谭c

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity UGUI_DropDown控件模拟QQ分组的使用心得相关的知识,希望对你有一定的参考价值。

关于 DropDown 很好用,但是也有很多坑,对比专门的软件开发工具,unity关于DropDown的功能有限,下面总结一下我本次使用DropDown的一些心得

DropDown下拉选项

DropDown创建即可运行,并生成初始选项,供我们参考使用,也非常简单,下面我讲讲使用方法:

上图我创建了一个DropDown,相关属性我就不说了,我讲讲怎么添加事件,和设置名称


我根据项目需求,选中后主标题是不会变化的,所以把CaptionText 控件置为空,这样我们就可以单独控制改文字的更改。


我的项目需求是有多少选项就会显示多少,所以去掉Template下的一些控件,并且去除掉Template身上的Scroll Rect组件。


上面步骤完成后,我们调整锚点,然后给Template添加两个组件,用于排列显示,和适应选项大小,现在我们就实现了有多少选项都会直接显示出来,下面我们进行事件绑定和实现qq分组折叠效果
上代码:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class DropdownScript : MonoBehaviour {

    
    public Text m_dropdownName;//名称
    public int m_ids = 0;//id
    private Dropdown m_dropdown;//控件
    private List<Dropdown.OptionData> optionDatas = new List<Dropdown.OptionData>();//选项
    private Action<int> DropDownEvent;//选项事件
    public Action<bool, int,float> OpenOrCloseEvent;//点击事件
    private void OnClickDropdown(int arg0)
    {
        if (DropDownEvent!=null)
        {
            DropDownEvent(arg0);
        }
    }
    /// <summary>
    /// 初始化下拉框
    /// </summary>
    /// <param name="name"></param>
    /// <param name="options"></param>
    public void InitDropdown(string name,int id,List<string> options)
    {
        m_ids = id;
        m_dropdown = this.transform.GetComponent<Dropdown>();
        m_dropdown.onValueChanged.AddListener(OnClickDropdown);
        m_dropdownName.text = name;
        m_dropdown.ClearOptions();
        if (options.Count>0&& options!=null)
        {
            for (int i = 0; i < options.Count; i++)
            {
                Dropdown.OptionData option = new Dropdown.OptionData();
                option.text = options[i];
                optionDatas.Add(option);
            }
        }
        m_dropdown.AddOptions(optionDatas);
    }
    /// <summary>
    /// 添加或者清空事件 不传参或者null清空事件
    /// </summary>
    /// <param name="action"></param>
    public void DropDownEventCtrl(Action<int> action=null)
    {
        DropDownEvent += action;
    }
    public void OnClickEventCtrl(Action<bool,int,float> action = null)
    {
        OpenOrCloseEvent += action;
    }

}

该代码挂在编辑好的DropDown上,由于DropDown没有展开和关闭的事件监听,所以我做了一个能够检测到展开关闭的事件OpenOrCloseEvent,思路是在点击展开时系统会生成一个叫做DropDown List的控件,该控件就是基于Template生成的,所以我写了一个脚本,专门在start和destory时触发OpenOrCloseEvent事件,看代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class TemplateEvent : MonoBehaviour {
    DropdownScript dropdownScript;
    float hight = 0;
    // Use this for initialization
    void Start () {
        dropdownScript = GetComponentInParent<DropdownScript>();
        hight = this.GetComponent<RectTransform>().rect.height+ dropdownScript.GetComponent<RectTransform>().rect.height;
        if (this.name == "Dropdown List")
        {
            if (dropdownScript.OpenOrCloseEvent != null)
            {
                
                dropdownScript.OpenOrCloseEvent(true, dropdownScript.m_ids, hight);
            }
        }
	}
	
	// Update is called once per frame
	void Update () {
		
	}
    private void OnDestroy()
    {
        if (this.name == "Dropdown List")
        {
            if (dropdownScript.OpenOrCloseEvent != null)
            {
                dropdownScript.OpenOrCloseEvent(false, dropdownScript.m_ids, hight);
            }
        }
    }
}

该脚本挂在Template上
OpenOrCloseEvent有三个参数:分别为bool(开启关闭),int(当前的DropDown),float(当前选项框的长度+DropDown高度),下面我们就来为这两个事件添加内容监听,主要是OpenOrCloseEvent

}using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;


public class SecondLevelPanel : MonoBehaviour {

    public DropdownScript m_dropdownScript;//下拉框预制体
    public Transform m_dropdownParent;//下拉框父物体

    List<DropdownScript> m_curDropdownScripts = new List<DropdownScript>();
    // Use this for initialization
    void Start () {
        List<string> options = new List<string>();
        for (int i = 0; i < 8; i++)
        {
            options.Add(("xx图片" + i));
        }
        for (int i = 0; i < 5; i++)
        {
            DropdownScript obj = Instantiate(m_dropdownScript, m_dropdownParent);
            float y = (-obj.GetComponent<RectTransform>().rect.height - 2 ) * i;
            Debug.Log("height : " + y);
            obj.GetComponent<RectTransform>().anchoredPosition = new Vector2(obj.GetComponent<RectTransform>().anchoredPosition.x, obj.GetComponent<RectTransform>().anchoredPosition.y+y);
            Debug.Log(obj.transform.localPosition);
            obj.InitDropdown("背景" + i,i, options);
            obj.DropDownEventCtrl(DropdownEvent);
            obj.OnClickEventCtrl(OnClickEvent);
            m_curDropdownScripts.Add(obj);
        }
	}
    /// <summary>
    /// 点击了控件的事件
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="index"></param>
    private void OnClickEvent(bool obj,int index,float hight)
    {
        if (obj)
        {
            foreach (var item in m_curDropdownScripts)
            {
                if (item.m_ids> index)
                {
                    float y = item.GetComponent<RectTransform>().anchoredPosition.y - hight;
                    item.GetComponent<RectTransform>().anchoredPosition = new Vector2(item.GetComponent<RectTransform>().anchoredPosition.x, y);
                }
            }
        }
        else
        {
            foreach (var item in m_curDropdownScripts)
            {
                if (item.m_ids > index)
                {
                    float y = item.GetComponent<RectTransform>().anchoredPosition.y + hight;
                    item.GetComponent<RectTransform>().anchoredPosition = new Vector2(item.GetComponent<RectTransform>().anchoredPosition.x, y);
                }
            }
        }
    }

    /// <summary>
    /// 下拉框事件
    /// </summary>
    /// <param name="obj"></param>
    private void DropdownEvent(int obj)
    {
        Debug.Log("进入 DropdownEvent");
    }

    // Update is called once per frame
    void Update () {
		
	}
}

该脚本挂载在主控物体上,可以是场景里的任意物体,但不能是预制体
具体思路:点击了DropDown,展开时触发展开事件,其他控件加上其高度,收回时触发事件,其他控件减去其高度,演示效果如下:

那么这个qq的分组效果就实现了,最终所有生成的DropDown其父节点在一个Scroll View上面,如果有多个分组可以以滑动的方式显示!
希望这边帖子能给大家带来帮助!

以上是关于Unity UGUI_DropDown控件模拟QQ分组的使用心得的主要内容,如果未能解决你的问题,请参考以下文章

C#怎么模拟鼠标点击

怎么在MFC对话框中实现模拟键盘输入

Delphi 如何操作外部程序的控件(如按钮,文本框,单选按钮等)

unity3d 能否通过控件嵌入其他软件中

unity3d怎么调整手机键盘的大小和位置??

unity UGUI的控件与UI组件组合后都有哪些妙用