Я создаю 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;
}
}