关于 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上面,如果有多个分组可以以滑动的方式显示!
希望这边帖子能给大家带来帮助!