unity3d - Unity:打开时动态更新下拉列表,同时不会失去对 InputField 的关注
问题描述
我正在创建一个Dropdown
顶部带有搜索栏的。基本上,我Inputfield
在Dropdown
.
当您单击 时Inputfield
,会Dropdown
打开,当您在其中输入内容时,Dropdown
应该会动态更新其列表。
这是我遇到的问题,Dropdown
检查器中的选项发生了变化,但是,它不会更新场景中的列表。
当我这样做时Dropdown.Hide()
,Dropdown.Show()
它会更新,但后来我失去了对Inputfield
. 我总是可以这样做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;
}
}
解决方案
要确保下拉选项列表 UI 是最新的,您需要禁用并重新启用该组件。
不幸的是,这会使下拉菜单“闪烁”。看看最后一个“无闪烁”的解决方案。
在这里,我使用了 TextMeshPro 下拉菜单。
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();
}
编辑 :
我找到了一种没有任何闪烁的方法来实现这一点。这涉及摆脱Dropdown
脚本并编写自己的脚本。
基本上,我采用了与下拉菜单相同的 UI,但我VerticalLayoutGroup
在ScrollRect
.
然后我编写了一个自定义脚本:
- 触发时显示
ScrollRect
并使用所有选项填充布局InputField.onSelect
- 通过在触发时隐藏选项来过滤选项
InputField.onValueChange
(使用油门) - 关闭
ScrollRect
何时InputField.onEndEdit
触发
并且还需要进行一些重要的更改:
- 应该有一个带有专用排序顺序的
ScrollRect
Canvas 脚本位于 UI 之上 ScrollRect
应该有一个GraphicsRaycaster
组件能够选择布局中的选项- 关闭
ScrollRect
ononEndEdit
应该延迟完成。否则,您的布局中的按钮将不会评估单击事件。
推荐阅读
- python - Python Pandas - 选择 .contains 的值
- angular - RxJS Observables - 如何调节可观察的回报
- android - xml可绘制或以编程方式绘制?
- reactjs - 刷新页面后反应路由器传递的数据丢失
- python - 在具有多个 '\n' 的字符串中查找子字符串
- unit-testing - 想模拟 DynamoHttpServletRequest 以通过 junit /mockito 中的测试属性
- apache-kafka - 如何在 Kafka 流聚合期间发布事件?
- sapui5 - UI5 中的内容安全策略 (CSP) 实现
- amazon-web-services - 在 AWS Cognito 中将 AWS SES 用于自定义消息
- node.js - Deno:如何处理异常