Unity3d Unity:打开时动态更新下拉列表,同时不丢失对InputField的关注
我正在创建一个顶部有搜索栏的Unity3d Unity:打开时动态更新下拉列表,同时不丢失对InputField的关注,unity3d,dropdown,input-field,Unity3d,Dropdown,Input Field,我正在创建一个顶部有搜索栏的下拉列表。基本上,我在下拉列表的顶部放置了一个Inputfield 当您单击输入字段时,将打开下拉列表,当您在其中键入内容时,下拉列表将动态更新其列表 这是我遇到的问题,检查器中的下拉列表选项发生了更改,但它不会更新场景中的列表。 当我执行下拉菜单.Hide()然后执行下拉菜单.Show()时,它会更新,但随后我会失去对输入字段的关注。我总是可以只做Inputfield.Select(),但是整个Inputfield会突出显示,您必须单击您所在的位置才能从您所在的位置
下拉列表。基本上,我在下拉列表的顶部放置了一个Inputfield
当您单击输入字段
时,将打开下拉列表
,当您在其中键入内容时,下拉列表
将动态更新其列表
这是我遇到的问题,检查器中的下拉列表
选项发生了更改,但它不会更新场景中的列表。
当我执行下拉菜单.Hide()
然后执行下拉菜单.Show()
时,它会更新,但随后我会失去对输入字段的关注。我总是可以只做Inputfield.Select()
,但是整个Inputfield
会突出显示,您必须单击您所在的位置才能从您所在的位置进行编辑
有什么建议吗
编辑
下面是代码。我把所有不重要的东西都拿出来,让它尽可能的苗条
public class SearchbarInput : InputField
{
private GameObject[] m_Ordnance;
private Dropdown m_Dropdown;
private SearchbarInput m_InputField;
// Needed for basic inputfield functionality
private List<string> m_OrdnanceNames = new List<string>(); // Used to display our data
protected override void Start()
{
m_Ordnance = GetComponent<OrdnanceSelector>().m_Ordnance;
// Get necessary components
m_Dropdown = GetComponentInParent<Dropdown>();
m_InputField = GetComponent<SearchbarInput>();
m_InputField.gameObject.GetComponentInChildren<Text>().text = "Click here to select Ordnance";
// Set InputField onValueChange listener
m_InputField.onValueChanged.AddListener(OnInputValueChanged);
// Add each ordnance name to our string list
foreach (GameObject ordnance in m_Ordnance)
{
if (ordnance != null) m_OrdnanceNames.Add(ordnance.name);
}
if (m_OrdnanceNames.Count == 0) DisplayError("Ordnance were not added");
else
{
ChangeDropdownOptions(m_OrdnanceNames);
m_Dropdown.onValueChanged.AddListener((index) => OnDropdownItemClicked(index));
}
base.Start();
}
// When the InputField is selected
public override void OnSelect(BaseEventData eventData)
{
base.OnSelect(eventData);
Debug.Log("SearchbarInput selected");
Dropdown parentDropdown = GetComponentInParent<Dropdown>();
parentDropdown.Show();
}
// When the InputField is deselected
public override void OnDeselect(BaseEventData eventData)
{
base.OnDeselect(eventData);
Debug.Log("SearchbarInput deselected");
}
/// Displays items in list that are similar to what the user typed in the Input Field
private void OnInputValueChanged(string typedText)
{
List<string> results = GetResults(typedText);
ChangeDropdownOptions(results);
}
/// Get list of items that contains characters similar to input
private List<string> GetResults(string input)
{
return m_OrdnanceNames.FindAll((str) => str.IndexOf(input) >= 0);
}
///============================== Dropdown Methods===================================
/// Called when the dropdown menu is clicked. Is set inside of scripts Start function
public void OnDropdownItemClicked(int index)
{
// Get selected ordnance name
string ordnanceName = m_Dropdown.options[index].text;
m_InputField.text = ordnanceName;
// Change AndyGenerator Prefab
int indexOfOrdnance = m_OrdnanceNames.IndexOf(ordnanceName);
//m_AndyScript.AndyPrefab = m_Ordnance[indexOfOrdnance]; <- Took out for StackOverflow to make as short as possible
}
/// Clears the dropdown options and add's options set inside of the list
private void ChangeDropdownOptions(List<string> options)
{
m_Dropdown.ClearOptions();
m_Dropdown.AddOptions(options);
}
///============================== Error Method===================================
/// Displays error inside of our InputField.
private void DisplayError(string errorText)
{
Debug.Log("Searchbar.cs: " + errorText);
// Decided to make it more obvious since this is absolutely needed and
// it saves the headache of looking for an error
m_InputField.text = "Error: " + errorText;
}
}
公共类SearchbarInput:InputField
{
私人游戏对象[]m_军械;
私人下拉菜单m_下拉菜单;
专用SearchbarInput m_InputField;
//需要基本的inputfield功能
private List m_OrdnanceNames=new List();//用于显示数据
受保护的覆盖无效开始()
{
m_armon=GetComponent().m_armon;
//获取必要的组件
m_Dropdown=getComponentParent();
m_InputField=GetComponent();
m_InputField.gameObject.getComponentChildren().text=“单击此处选择”;
//将InputField设置为ValueChange侦听器
m_InputField.onValueChanged.AddListener(OnInputValueChanged);
//将每个军械名称添加到我们的字符串列表中
foreach(m_军械中的游戏对象军械)
{
如果(armonment!=null)m_OrdnanceNames.Add(armonment.name);
}
如果(m_OrdnanceNames.Count==0)显示错误(“未添加弹药”);
其他的
{
更改下拉选项(m_或nanceName);
m_Dropdown.onValueChanged.AddListener((索引)=>OnDropdownItemClicked(索引));
}
base.Start();
}
//选择输入字段时
公共覆盖无效OnSelect(BaseEventData事件数据)
{
base.OnSelect(事件数据);
Log(“已选择SearchbarInput”);
Dropdown parentDropdown=getComponentParent();
parentDropdown.Show();
}
//取消选择InputField时
公共覆盖无效OnDeselect(BaseEventData事件数据)
{
base.OnDeselect(eventData);
Log(“SearchbarInput取消选中”);
}
///显示列表中与用户在输入字段中键入的内容类似的项目
私有void OnInputValueChanged(字符串类型文本)
{
列表结果=GetResults(typedText);
更改下拉选项(结果);
}
///获取包含类似于输入的字符的项目列表
私有列表GetResults(字符串输入)
{
返回m_OrdnanceNames.FindAll((str)=>str.IndexOf(input)>=0);
}
///=================================================下拉方法===================================
///单击下拉菜单时调用。在脚本开始函数中设置
公共void OnDropdownItemClicked(整数索引)
{
//获取选定的名称
字符串ORDNACENAME=m_下拉列表。选项[索引]。文本;
m_InputField.text=ordnanceName;
//更改ANDY生成器预制件
int indexofrance=m_ordnanceName.IndexOf(ordnanceName);
//m_AndyScript.AndyPrefab=m_ammonth[indexofrance];我不知道这个答案,但我有一个类似的问题……我让这个搜索栏工作,有一个显示动态值的下拉列表,但这个下拉列表只更新奇数字符(在第一个、第三个…不是在第二个、第四个…)
在这里:
//只要输入字段改变(偶数或奇数),就调用它的工作状态
public void newSearchFieldValueChanged()
{
//读取输入字段,确定。。。
searchText=newSearchField.text;
//空时返回。。。
if(string.IsNullOrEmpty(searchText))返回;
//我需要隐藏下拉列表
dropdown.Hide();
//清除旧选项
ClearOptions();
//这是一个用于填充下拉选项的词典,请清除它
dicTemp.Clear();
//添加第一个空值
添加命令(“,”0“);
//所以我运行另一个dic,它不会改变它的原始值
对于(int i=0;i
同样,它在第一个字母和第三个字母上工作……但在第二个和第四个字母上不工作,下拉列表不会显示(除了每次调用该函数)。@rayarato
我想
m_InputField.ActivateInputField()
应该对您有用,因为您在编辑器上禁用了“OnFocus-Select All”。它对我有用。要确保下拉选项列表UI是最新的,您需要禁用并启用该组件
不幸的是,这
//call whenever the input field changes, even OR odd, its working
public void newSearchFieldValueChanged()
{
//read the input field, ok...
searchText = newSearchField.text;
//return when empty...
if (string.IsNullOrEmpty(searchText)) return;
//I need to hide the dropdown
dropdown.Hide();
//clear its old options
dropdown.ClearOptions();
//this is a dictionary to fill the dropdown options, clear it
dicTemp.Clear();
//add a first empty value
dicTemp.Add("", "0");
//so I run for another dic, that dont change its original values
for (int i = 0; i < dic.Keys.Count; i++)
{
//if it contains in its keys the word typed in the search bar...
if (dic.Keys.ElementAt(i).ToLower().Contains(searchText.ToLower()))
{
//I add it to the cleared dicTemp that will fill the dropdown options
dicTemp.Add(dic.Keys.ElementAt(i), dic.Values.ElementAt(i));
}
}
//fill the dropdown options with the new dicTemp, each time something changes
dropdown.AddOptions(dicTemp.Keys.ToList());
//duh
dropdown.Show();
//keep the focus on input field to continue type (dropdown selected by mouse)
newSearchField.ActivateInputField();
}
Dropdown.ClearOptions();
Dropdown.AddOptions(options);
Dropdown.RefreshOptions();
InputField.Input.ActivateInputField();
/// <summary>
/// Call this after modifying options while the dropdown is displayed
/// to make sure the visual is up to date.
/// </summary>
public static void RefreshOptions(this TMPro.TMP_Dropdown dropdown)
{
dropdown.enabled = false;
dropdown.enabled = true;
dropdown.Show();
}