我正在创建一个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;
}
}
答案 0 :(得分:1)
要确保下拉选项列表用户界面是最新的,您需要禁用并启用该组件。
不幸的是,这使下拉列表“闪烁”。最后看一下“不闪烁”的解决方案。
在这里,我正在使用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
的UI顶部应具有Canvas脚本和专用的“排序顺序” ScrollRect
应该有一个GraphicsRaycaster
组件才能选择版式中的选项ScrollRect
上关闭onEndEdit
的操作应延迟。否则,您的布局中的按钮将不会评估click事件。答案 1 :(得分:0)
我不知道那个答案,但是我有一个类似的问题...我使此搜索栏起作用,并且下拉列表显示了动态值,但是此下拉列表仅更新了 odd 字符(在第一,第三...不在第二,第四...)
这里:
//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();
}
同样,它在第一个字母和第三个字母上起作用...但是在第二个和第四个字母上不起作用,下拉列表不显示(因为每次都调用该功能)...
答案 2 :(得分:0)
@Rayaarito
我认为
m_InputField.ActivateInputField();
应该为您工作,因为您在编辑器上禁用了“ OnFocus-全选”。它对我有用。