Xamarin.Forms Pesquisa de shell

Download Sample Baixe o exemplo

Xamarin.Forms O Shell inclui a funcionalidade de pesquisa integrada fornecida pela SearchHandler classe. O recurso de pesquisa pode ser adicionado a uma página definindo a propriedade anexada Shell.SearchHandler como um objeto subclassificado SearchHandler . Isso faz com que uma caixa de pesquisa seja adicionada na parte superior da página:

Screenshot of a Shell SearchHandler, on iOS and Android

Quando uma consulta é inserida na caixa de pesquisa, a propriedade Query é atualizada e, em cada atualização, o método OnQueryChanged é executado. Esse método pode ser substituído para preencher a área de sugestões de pesquisa com dados:

Screenshot of a search results in a Shell SearchHandler, on iOS and Android

Em seguida, quando um resultado é selecionado na área de sugestões de pesquisa, o método OnItemSelected é executado. Esse método pode ser substituído para responder apropriadamente, por exemplo, navegando para uma página de detalhes.

Criar um SearchHandler

A funcionalidade de pesquisa pode ser adicionada a um aplicativo Shell criando subclasses da classe SearchHandler e substituindo os métodos OnQueryChanged e OnItemSelected:

public class AnimalSearchHandler : SearchHandler
{
    public IList<Animal> Animals { get; set; }
    public Type SelectedItemNavigationTarget { get; set; }

    protected override void OnQueryChanged(string oldValue, string newValue)
    {
        base.OnQueryChanged(oldValue, newValue);

        if (string.IsNullOrWhiteSpace(newValue))
        {
            ItemsSource = null;
        }
        else
        {
            ItemsSource = Animals
                .Where(animal => animal.Name.ToLower().Contains(newValue.ToLower()))
                .ToList<Animal>();
        }
    }

    protected override async void OnItemSelected(object item)
    {
        base.OnItemSelected(item);

        // Let the animation complete
        await Task.Delay(1000);

        ShellNavigationState state = (App.Current.MainPage as Shell).CurrentState;
        // The following route works because route names are unique in this application.
        await Shell.Current.GoToAsync($"{GetNavigationTarget()}?name={((Animal)item).Name}");
    }

    string GetNavigationTarget()
    {
        return (Shell.Current as AppShell).Routes.FirstOrDefault(route => route.Value.Equals(SelectedItemNavigationTarget)).Key;
    }
}

A substituição de OnQueryChanged tem dois argumentos: oldValue, que contém a consulta de pesquisa anterior, e newValue, que contém a consulta de pesquisa atual. A área de sugestões de pesquisa pode ser atualizada, definindo-se a propriedade SearchHandler.ItemsSource como uma coleção IEnumerable que contém itens que correspondem à consulta de pesquisa atual.

Quando um resultado de pesquisa é selecionado pelo usuário, a substituição de OnItemSelected é executada, e a propriedade SelectedItem é definida. Nesse exemplo, o método navega para outra página que exibe os dados sobre o Animal selecionado. Para obter mais informações sobre navegação, consulte Xamarin.Forms Navegação do shell.

Observação

As propriedades SearchHandler adicionais podem ser definidas para controlar a aparência da caixa de pesquisa.

Criar um SearchHandler

O subclassificado SearchHandler pode ser consumido definindo a Shell.SearchHandler propriedade anexada para um objeto do tipo subclassificado, na página de consumo:

<ContentPage ...
             xmlns:controls="clr-namespace:Xaminals.Controls">
    <Shell.SearchHandler>
        <controls:AnimalSearchHandler Placeholder="Enter search term"
                                      ShowsResults="true"
                                      DisplayMemberName="Name" />
    </Shell.SearchHandler>
    ...
</ContentPage>

Este é o código C# equivalente:

Shell.SetSearchHandler(this, new AnimalSearchHandler
{
    Placeholder = "Enter search term",
    ShowsResults = true,
    DisplayMemberName = "Name"
});

O método AnimalSearchHandler.OnQueryChanged retorna um List de objetos Animal. A propriedade DisplayMemberName é definida como a propriedade Name de cada objeto Animal e, portanto, os dados exibidos na área de sugestões serão cada nome de animal.

A propriedade ShowsResults é definida como true, de modo que as sugestões de pesquisa são exibidas enquanto o usuário insere uma consulta de pesquisa:

Screenshot of search results in a Shell SearchHandler, on iOS and Android, with results for the partial string M.

À medida que a consulta de pesquisa muda, a área de sugestões da pesquisa é atualizada:

Screenshot of search results in a Shell SearchHandler, on iOS and Android, with results for the partial string M o n.

Quando um resultado de pesquisa é selecionado, o é navegado para e uma página de detalhes sobre o MonkeyDetailPage macaco selecionado é exibida:

Screenshot of monkey details, on iOS and Android

Definir a aparência do item dos resultados da pesquisa

Além de exibir os dados string nos resultados da pesquisa, a aparência de cada item do resultado da pesquisa pode ser definida configurando a propriedade SearchHandler.ItemTemplate como DataTemplate:

<ContentPage ...
             xmlns:controls="clr-namespace:Xaminals.Controls">    
    <Shell.SearchHandler>
        <controls:AnimalSearchHandler Placeholder="Enter search term"
                                      ShowsResults="true">
            <controls:AnimalSearchHandler.ItemTemplate>
                <DataTemplate>
                    <Grid Padding="10"
                          ColumnDefinitions="0.15*,0.85*">
                        <Image Source="{Binding ImageUrl}"
                               HeightRequest="40"
                               WidthRequest="40" />
                        <Label Grid.Column="1"
                               Text="{Binding Name}"
                               FontAttributes="Bold"
                               VerticalOptions="Center" />
                    </Grid>
                </DataTemplate>
            </controls:AnimalSearchHandler.ItemTemplate>
       </controls:AnimalSearchHandler>
    </Shell.SearchHandler>
    ...
</ContentPage>

Este é o código C# equivalente:

Shell.SetSearchHandler(this, new AnimalSearchHandler
{
    Placeholder = "Enter search term",
    ShowsResults = true,
    ItemTemplate = new DataTemplate(() =>
    {
        Grid grid = new Grid { Padding = 10 };
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(0.15, GridUnitType.Star) });
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(0.85, GridUnitType.Star) });

        Image image = new Image { HeightRequest = 40, WidthRequest = 40 };
        image.SetBinding(Image.SourceProperty, "ImageUrl");
        Label nameLabel = new Label { FontAttributes = FontAttributes.Bold, VerticalOptions = LayoutOptions.Center };
        nameLabel.SetBinding(Label.TextProperty, "Name");

        grid.Children.Add(image);
        grid.Children.Add(nameLabel, 1, 0);
        return grid;
    })
});

Os elementos especificados em DataTemplate definem a aparência de cada item na área de sugestões. Neste exemplo, o layout dentro do DataTemplate é gerenciado por um Grid. O Grid contém um objeto Image e um objeto Label, que se ligam a propriedades de cada objeto Monkey.

As capturas de tela a seguir mostram o resultado dos modelos de cada item na área de sugestões:

Screenshot of templated search results in a Shell SearchHandler, on iOS and Android

Para obter mais informações sobre modelos de dados, consulte Xamarin.Forms modelos de dados.

Visibilidade da caixa de pesquisa

Por padrão, quando um SearchHandler é adicionado na parte superior de uma página, a caixa de pesquisa fica visível e totalmente expandida. No entanto, esse comportamento pode ser alterado definindo a propriedade SearchHandler.SearchBoxVisibility para um dos membros da enumeração SearchBoxVisibility:

  • Hidden – a caixa de pesquisa não está visível ou acessível.
  • Collapsible – a caixa de pesquisa está oculta até que o usuário execute uma ação para mostrá-la. No iOS, a caixa de pesquisa é revelada ao saltar verticalmente o conteúdo da página, e no Android a caixa de pesquisa é revelada tocando no ícone de ponto de interrogação.
  • Expanded – a caixa de pesquisa está visível e totalmente expandida. Este é o valor padrão da propriedade SearchBoxVisibility.

Importante

No iOS, uma caixa de pesquisa dobrável requer o iOS 11 ou superior.

O exemplo a seguir mostra como ocultar a caixa de pesquisa:

<ContentPage ...
             xmlns:controls="clr-namespace:Xaminals.Controls">
    <Shell.SearchHandler>
        <controls:AnimalSearchHandler SearchBoxVisibility="Hidden"
                                      ... />
    </Shell.SearchHandler>
    ...
</ContentPage>

Foco na caixa de pesquisa

Tocar na caixa de pesquisa invoca o teclado na tela, e a caixa de pesquisa recebe o foco de entrada. Isso também pode ser feito de forma programática chamando o método Focus, que tenta definir o foco de entrada na caixa de pesquisa e retornará true se for bem-sucedido. Quando o foco passa para a caixa de pesquisa, o evento Focused é acionado, e o método OnFocused substituível é chamado.

Quando o foco de entrada estiver em uma caixa de pesquisa, tocar em qualquer parte da tela fará o teclado na tela desaparecer e a caixa de pesquisa perder o foco de entrada. Isso também poderá ser feito de forma programática chamando o método Unfocus. Quando a caixa de pesquisa perde o foco, o evento Unfocused é acionado, e o método OnUnfocus substituível é chamado.

O estado do foco de uma caixa de pesquisa poderá ser recuperado por meio da propriedade IsFocused, que retornará true se um SearchHandler estiver com o foco de entrada no momento.

Teclado do SearchHandler

O teclado que é exibido quando um usuário interage com um SearchHandler pode ser definido de forma programática por meio da propriedade do Keyboard, para uma das seguintes propriedades da classe Keyboard:

  • Chat – usado para mensagens de texto e lugares em que os emojis são úteis.
  • Default – o teclado padrão.
  • Email – usado ao inserir endereços de email.
  • Numeric – usado ao inserir números.
  • Plain – usado ao inserir texto, sem nenhum KeyboardFlags especificado.
  • Telephone – usado ao inserir números de telefone.
  • Text – usado ao inserir texto.
  • Url – usado para inserir caminhos de arquivos e endereços web.

Isso pode ser feito no XAML da seguinte maneira:

<SearchHandler Keyboard="Email" />

Este é o código C# equivalente:

SearchHandler searchHandler = new SearchHandler { Keyboard = Keyboard.Email };

A classe Keyboard também tem um método de fábrica Create que pode ser usado para personalizar um teclado especificando o comportamento de capitalização, de verificação ortográfica e de sugestão. Os valores de enumeração KeyboardFlags são especificados como argumentos para o método, e um Keyboard personalizado é retornado. A enumeração KeyboardFlags contém os seguintes valores:

  • None – nenhum recurso é adicionado ao teclado.
  • CapitalizeSentence – indica que as primeiras letras das primeiras palavras de cada frase serão automaticamente maiúsculas.
  • Spellcheck – indica que a verificação ortográfica será executada no texto digitado.
  • Suggestions – indica que os preenchimentos de palavra sugerida será realizado no texto digitado.
  • CapitalizeWord – indica que a primeira letra de cada palavra será automaticamente maiúscula.
  • CapitalizeCharacter – indica que todos os caracteres serão automaticamente colocados em maiúsculas.
  • CapitalizeNone – indica que não ocorrerá nenhuma capitalização automática ocorrerá.
  • All – indica que a verificação ortográfica, os preenchimentos de palavra sugerida e a capitalização de frases ocorrerão no texto digitado.

O seguinte exemplo de código XAML mostra como personalizar o Keyboard padrão para oferecer preenchimentos de palavra sugerida e capitalizar todos os caracteres inseridos:

<SearchHandler Placeholder="Enter search terms">
    <SearchHandler.Keyboard>
        <Keyboard x:FactoryMethod="Create">
            <x:Arguments>
                <KeyboardFlags>Suggestions,CapitalizeCharacter</KeyboardFlags>
            </x:Arguments>
        </Keyboard>
    </SearchHandler.Keyboard>
</SearchHandler>

Este é o código C# equivalente:

SearchHandler searchHandler = new SearchHandler { Placeholder = "Enter search terms" };
searchHandler.Keyboard = Keyboard.Create(KeyboardFlags.Suggestions | KeyboardFlags.CapitalizeCharacter);