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