Je crée un Dropdown
avec une barre de recherche en haut. En gros, je mets un Inputfield
en haut du Dropdown
.
Lorsque vous cliquez sur le Champ de saisie
, la Liste déroulante
s'ouvre et lorsque vous y tapez quelque chose, la Liste déroulante
doit mettre à jour sa liste de manière dynamique. / p>
Voici le problème que j'ai, l'option Dropdown
change dans l'inspecteur, cependant, elle ne met pas à jour la liste dans la scène.
Quand je fais Dropdown.Hide ()
puis Dropdown.Show ()
, il se met à jour mais je perds le focus sur le Inputfield . Je peux toujours simplement faire
Inputfield.Select ()
mais ensuite tout le Inputfield
est mis en surbrillance et vous devez cliquer sur la position où vous étiez pour pouvoir modifier à partir de là où vous étiez .
Des suggestions?
Modifier Voici le code ci-dessous. J'ai pris toutes les choses sans importance pour le rendre aussi mince que possible à montrer ici
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; } }
3 Réponses :
Je ne connais pas cette réponse, mais j'ai un problème similaire ... J'ai fait fonctionner cette barre de recherche, avec un menu déroulant affichant les valeurs dynamiques, mais ce menu déroulant ne met à jour que les caractères impairs (sur la première, la troisième ... pas la deuxième, la quatrième ...)
Ici:
//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(); }
Encore une fois, cela fonctionne sur la première lettre, et la troisième ... mais pas sur le deuxième et le quatrième, la liste déroulante NE S'AFFICHE PAS (en plus de la fonction est appelée à chaque fois) ...
Même problème exact ici. J'ai essayé de retarder les appels avec une co-routine mais cela n'aide pas.
@Rayaarito
Je pense
m_InputField.ActivateInputField ();
Cela devrait fonctionner pour vous, puisque vous désactivez "OnFocus - Select All" dans l'éditeur. Cela a fonctionné pour moi.
Pour vous assurer que l'interface utilisateur de la liste déroulante des options est à jour, vous devez désactiver et réactiver le composant.
Malheureusement, cela fait «scintiller» la liste déroulante. Regardez à la fin une solution "sans scintillement".
Ici, j'utilise une liste déroulante TextMeshPro.
/// <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(); }
Avec la méthode d'extension suivante :
Dropdown.ClearOptions(); Dropdown.AddOptions(options); Dropdown.RefreshOptions(); InputField.Input.ActivateInputField();
MODIFIER:
J'ai trouvé un moyen d'y parvenir ceci sans aucun scintillement. Cela implique de se débarrasser du script Dropdown
et d'écrire le vôtre.
En gros, j'ai pris la même interface que pour la liste déroulante, mais j'ai placé un VerticalLayoutGroup code > dans le contenu du
ScrollRect
.
J'ai ensuite écrit un script personnalisé qui:
ScrollRect
et remplir la mise en page avec toutes les options lorsque InputField.onSelect
est déclenché InputField.onValueChange
est déclenché (avec accélérateur) ScrollRect
lorsque InputField.onEndEdit
est déclenché Et il y a des changements importants qui doivent également être apportés:
ScrollRect
doit avoir un script Canvas avec un ordre de tri dédié pour être au-dessus de l'interface utilisateur ScrollRect
doit avoir un composant GraphicsRaycaster
pour pouvoir sélectionner les options dans la mise en page ScrollRect
sur onEndEdit
doit être effectuée avec un délai. Sinon, l'événement de clic ne sera pas évalué par les boutons de votre mise en page.
pourriez-vous s'il vous plaît ajouter un exemple de votre code actuel pour avoir un point de départ?
@derHugo Je viens d'ajouter du code. Je vous remercie