Xamarin.Forms Shell 검색

Download Sample 샘플 다운로드

Xamarin.Forms Shell에는 SearchHandler 클래스에서 제공하는 통합 검색 기능이 포함되어 있습니다. 검색 기능은 Shell.SearchHandler 연결된 속성을 서브클래싱된 SearchHandler 개체로 설정하여 페이지에 추가할 수 있습니다. 이를 통해 검색 상자가 페이지 위쪽에 추가됩니다.

Screenshot of a Shell SearchHandler, on iOS and Android

검색 상자에 쿼리를 입력하면 Query 속성이 업데이트되고 업데이트될 때마다 OnQueryChanged 메서드가 실행됩니다. 데이터를 사용하여 검색 제안 영역을 채우도록 이 메서드를 재정의할 수 있습니다.

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

그런 다음 검색 제안 영역에서 결과를 선택하면 OnItemSelected 메서드가 실행됩니다. 이 메서드는 세부 정보 페이지 탐색 등의 방법으로 응답이 적절히 이루어지도록 재정의할 수 있습니다.

SearchHandler 만들기

검색 기능은 SearchHandler 클래스를 서브클래싱하고 OnQueryChangedOnItemSelected 메서드를 재정의하여 Shell 애플리케이션에 추가할 수 있습니다.

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;
    }
}

OnQueryChanged는 이전 검색 쿼리를 포함하는 oldValue와 현재 검색 쿼리를 포함하는 newValue라는 두 인수를 재정의합니다. 검색 제안 영역은 SearchHandler.ItemsSource 속성을 현재 검색 쿼리와 일치하는 항목이 포함된 IEnumerable 컬렉션으로 설정하여 업데이트할 수 있습니다.

사용자가 검색 결과를 선택하면 OnItemSelected 재정의가 실행되고 SelectedItem 속성이 설정됩니다. 이 예제에서는 메서드가 선택된 Animal에 대한 데이터를 표시하는 다른 페이지로 이동합니다. 탐색에 대한 자세한 내용은 Xamarin.Forms Shell 탐색을 참조하세요.

참고 항목

추가 SearchHandler 속성을 설정하여 검색 상자 모양을 제어할 수 있습니다.

SearchHandler 사용

서브클래싱된 SearchHandler는 사용 중인 페이지에서 Shell.SearchHandler 연결된 속성을 서브클래싱된 형식의 개체로 설정하여 사용할 수 있습니다.

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

해당하는 C# 코드는 다음과 같습니다.

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

AnimalSearchHandler.OnQueryChanged 메서드는 Animal 개체의 List를 반환합니다. DisplayMemberName 속성은 각 Animal 개체의 Name 속성으로 설정되므로 제안 영역에 표시되는 데이터는 각 동물 이름이 됩니다.

ShowsResults 속성은 true로 설정되므로 사용자가 검색 쿼리를 입력할 때 검색 제안이 표시됩니다.

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

검색 쿼리가 변경되면 검색 제안 영역이 업데이트됩니다.

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

검색 결과를 선택하면 MonkeyDetailPage로 이동되고 선택한 원숭이에 대한 세부 정보 페이지가 표시됩니다.

Screenshot of monkey details, on iOS and Android

검색 결과 항목 모양 정의

검색 결과에 string 데이터를 표시하는 것 외에도, SearchHandler.ItemTemplate 속성을 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>

해당하는 C# 코드는 다음과 같습니다.

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;
    })
});

DataTemplate에 지정된 요소는 제안 영역에 있는 각 항목의 모양을 정의합니다. 이 예제에서 DataTemplate 내의 레이아웃은 Grid로 관리합니다. GridImage 개체 및 Label 개체를 포함하고, 두 개체는 모두 각 Monkey 개체의 속성에 바인딩됩니다.

다음 스크린샷은 제안 영역에서 각 항목을 템플릿화한 결과를 보여 줍니다.

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

데이터 템플릿에 대한 자세한 내용은 Xamarin.Forms 데이터 템플릿을 참조하세요.

검색 상자 표시 여부

기본적으로 SearchHandler가 페이지 맨 위에 추가되면 검색 상자가 표시되고 완전히 확장됩니다. 그러나 이 동작은 SearchHandler.SearchBoxVisibility 속성을 SearchBoxVisibility 열거형 멤버 중 하나로 설정하여 변경할 수 있습니다.

  • Hidden – 검색 상자가 표시되지 않거나 액세스할 수 없습니다.
  • Collapsible – 사용자가 검색 상자를 표시하는 작업을 수행할 때까지 검색 상자가 숨겨집니다. iOS에서 검색 상자는 페이지 콘텐츠를 세로로 튕기면 표시되고 Android에서는 물음표 아이콘을 누르면 검색 상자가 표시됩니다.
  • Expanded – 검색 상자가 표시되고 완전히 확장됩니다. SearchBoxVisibility 속성의 기본값입니다.

Important

iOS에서 축소 가능한 검색 상자 기능을 사용하려면 iOS 11 이상 버전이 필요합니다.

다음 예제에서는 검색 상자를 숨기는 방법을 보여 줍니다.

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

검색 상자 포커스

검색 상자를 탭하면 화상 키보드가 호출되고 검색 상자에 입력 포커스가 나타납니다. 이 작업은 검색 상자에 입력 포커스를 설정하려고 하고 성공하면 true를 반환하는 Focus 메서드를 호출하여 프로그래밍 방식으로 수행할 수도 있습니다. 검색 상자에 포커스가 있으면 Focused 이벤트가 발생하고 재정의 가능한 OnFocused 메서드가 호출됩니다.

검색 상자에 입력 포커스가 있는 경우 화면에서 다른 부분을 탭하면 화상 키보드가 해제되고 검색 상자의 입력 포커스가 사라집니다. 이 작업은 Unfocus 메서드를 호출하여 프로그래밍 방식으로 수행할 수도 있습니다. 검색 상자에서 포커스가 사라지면 Unfocused 이벤트가 발생하고 재정의 가능한 OnUnfocus 메서드가 호출됩니다.

검색 상자의 포커스 상태는 SearchHandler에 현재 입력 포커스가 있으면 true를 반환하는 IsFocused 속성을 통해 검색할 수 있습니다.

SearchHandler 키보드

사용자가 SearchHandler와 상호 작용할 때 표시되는 키보드는 Keyboard 속성을 통해 Keyboard 클래스의 다음 속성 중 하나로 프로그래밍 방식으로 설정할 수 있습니다.

  • Chat – 텍스트 작성 및 이모티콘이 유용한 경우에 사용합니다.
  • Default – 기본 키보드입니다.
  • Email – 전자 메일 주소를 입력할 때 사용합니다.
  • Numeric – 숫자를 입력할 때 사용합니다.
  • Plain – 지정된 KeyboardFlags 없이 텍스트를 입력할 때 사용합니다.
  • Telephone – 전화 번호를 입력할 때 사용합니다.
  • Text – 텍스트를 입력할 때 사용합니다.
  • Url – 파일 경로 및 웹 주소를 입력하는 데 사용합니다.

이렇게 하면 다음과 같이 XAML로 수행할 수 있습니다.

<SearchHandler Keyboard="Email" />

해당하는 C# 코드는 다음과 같습니다.

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

또한 Keyboard 클래스에는 대소문자, 맞춤법 검사 및 제안 동작을 지정하여 키보드를 사용자 지정하는 데 사용할 수 있는 Create 팩터리 메서드가 있습니다. KeyboardFlags 열거형 값은 사용자 지정된 Keyboard가 반환되는 메서드에 대한 인수로 지정됩니다. KeyboardFlags 열거는 다음 값을 포함합니다.

  • None – 키보드에 추가되는 기능이 없습니다.
  • CapitalizeSentence – 입력된 각 문장의 첫 번째 단어의 첫 문자가 자동으로 대문자로 시작함을 나타냅니다.
  • Spellcheck - 입력한 텍스트에 대해 맞춤법 검사를 수행할지를 나타냅니다.
  • Suggestions - 입력한 텍스트에 대해 완성된 단어를 제안할지를 나타냅니다.
  • CapitalizeWord – 각 단어의 첫 문자가 자동으로 대문자로 시작함을 나타냅니다.
  • CapitalizeCharacter – 모든 문자가 자동으로 대문자로 시작함을 나타냅니다.
  • CapitalizeNone – 자동 대소문자 표시가 이루어지지 않음을 나타냅니다.
  • All – 입력한 텍스트에 대해 맞춤법 검사, 단어 완성 및 문장 첫 글자 대문자 입력이 이루어질 것임을 나타냅니다.

다음 XAML 코드 예제에서는 완성 단어를 제안하고 입력한 모든 글자를 대문자로 시작하도록 기본 Keyboard를 사용자 지정하는 방법을 보여 줍니다.

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

해당하는 C# 코드는 다음과 같습니다.

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