검색창을 사용하여 검색 기능을 구현합니다. 검색창은 사용자가 키워드 또는 문구를 입력하여 앱 내에서 관련 결과를 표시할 수 있는 영구 검색 필드이며, 검색이 앱의 주요 초점인 경우에 권장됩니다.
API 노출 영역
SearchBar 구성 가능한 함수를 사용하여 검색창을 구현합니다. 이 구성 가능한 함수의 주요 매개변수는 다음과 같습니다.
inputField: 검색창의 입력란을 정의합니다. 일반적으로SearchBarDefaults.InputField를 활용하여 다음을 맞춤설정할 수 있습니다.query: 입력란에 표시할 쿼리 텍스트입니다.onQueryChange: 쿼리 문자열의 변경사항을 처리하는 람다입니다.
expanded: 검색창이 확장되어 추천 검색어 또는 필터링된 결과를 표시하는지 나타내는 불리언입니다.onExpandedChange: 드롭다운의 확장된 상태 변경사항을 처리하는 람다입니다.content:inputField아래에 검색 결과를 표시하는 이 검색창의 콘텐츠입니다.
추천 검색어가 있는 검색창
이 스니펫은 추천 검색어가 있는 SearchBar의 기본 구현을 보여줍니다.
@OptIn(ExperimentalMaterial3Api::class) @Composable fun SimpleSearchBar( textFieldState: TextFieldState, onSearch: (String) -> Unit, searchResults: List<String>, modifier: Modifier = Modifier ) { // Controls expansion state of the search bar var expanded by rememberSaveable { mutableStateOf(false) } Box( modifier .fillMaxSize() .semantics { isTraversalGroup = true } ) { SearchBar( modifier = Modifier .align(Alignment.TopCenter) .semantics { traversalIndex = 0f }, inputField = { SearchBarDefaults.InputField( query = textFieldState.text.toString(), onQueryChange = { textFieldState.edit { replace(0, length, it) } }, onSearch = { onSearch(textFieldState.text.toString()) expanded = false }, expanded = expanded, onExpandedChange = { expanded = it }, placeholder = { Text("Search") } ) }, expanded = expanded, onExpandedChange = { expanded = it }, ) { // Display search results in a scrollable column Column(Modifier.verticalScroll(rememberScrollState())) { searchResults.forEach { result -> ListItem( headlineContent = { Text(result) }, modifier = Modifier .clickable { textFieldState.edit { replace(0, length, result) } expanded = false } .fillMaxWidth() ) } } } } }
코드에 관한 핵심 사항
rememberSaveable은 검색창이 확장되었는지 또는 축소되었는지 구성 변경 전반에 걸쳐 유지되도록 합니다. 구성 변경 중에 활동이 소멸되기 전에 기억된 값을 호스팅 활동의savedInstanceState번들에 씁니다.semantics수정자는 TalkBack 탐색 순서를 제어합니다.isTraversalGroup은 모든 하위 구성 가능한 함수를 그룹화하도록Box에 설정됩니다.traversalIndex는 TalkBack이 각 그룹 피어에서 접근성 정보를 읽는 순서를 지정하도록 설정됩니다. TalkBack은 양수 값(예:1)이 있는 피어 보다 음수 값(예:-1)이 있는 피어의 접근성 정보를 읽습니다. 값은 부동 소수점이므로 각 피어에서-1.0과1.0사이의 값을 설정하여 여러 피어의 맞춤 순서를 지정할 수 있습니다.
SearchBar에는 사용자 입력을 위한inputField와 추천 검색어를 표시하는Column이(가) 포함되어 있습니다.SearchBarDefaults.InputField는 입력란을 만들고 사용자 쿼리의 변경사항을 처리합니다.onQueryChange는 텍스트 입력을 처리하고 입력란의 텍스트가 변경될 때마다 상태를 업데이트합니다.expanded상태는 추천 검색어 목록의 공개 상태를 제어합니다.
searchResults.forEach { result -> … }는searchResults목록을 반복하고 각 결과에ListItem를 만듭니다.ListItem을 클릭하면textFieldState가 업데이트되고 검색창이 축소되며 선택한 검색 결과로textField가 채워집니다.
결과
필터링된 목록이 있는 검색창
이 예에서는 사용자의 검색어를 기반으로 목록을 필터링하는 SearchBar를 보여줍니다.
@OptIn(ExperimentalMaterial3Api::class) @Composable fun CustomizableSearchBar( query: String, onQueryChange: (String) -> Unit, onSearch: (String) -> Unit, searchResults: List<String>, onResultClick: (String) -> Unit, modifier: Modifier = Modifier, // Customization options placeholder: @Composable () -> Unit = { Text("Search") }, leadingIcon: @Composable (() -> Unit)? = { Icon(Icons.Default.Search, contentDescription = "Search") }, trailingIcon: @Composable (() -> Unit)? = null, supportingContent: (@Composable (String) -> Unit)? = null, leadingContent: (@Composable () -> Unit)? = null, ) { // Track expanded state of search bar var expanded by rememberSaveable { mutableStateOf(false) } Box( modifier .fillMaxSize() .semantics { isTraversalGroup = true } ) { SearchBar( modifier = Modifier .align(Alignment.TopCenter) .semantics { traversalIndex = 0f }, inputField = { // Customizable input field implementation SearchBarDefaults.InputField( query = query, onQueryChange = onQueryChange, onSearch = { onSearch(query) expanded = false }, expanded = expanded, onExpandedChange = { expanded = it }, placeholder = placeholder, leadingIcon = leadingIcon, trailingIcon = trailingIcon ) }, expanded = expanded, onExpandedChange = { expanded = it }, ) { // Show search results in a lazy column for better performance LazyColumn { items(count = searchResults.size) { index -> val resultText = searchResults[index] ListItem( headlineContent = { Text(resultText) }, supportingContent = supportingContent?.let { { it(resultText) } }, leadingContent = leadingContent, colors = ListItemDefaults.colors(containerColor = Color.Transparent), modifier = Modifier .clickable { onResultClick(resultText) expanded = false } .fillMaxWidth() .padding(horizontal = 16.dp, vertical = 4.dp) ) } } } } }
코드에 관한 핵심 사항
- 사용자가 검색창에 텍스트를 입력하거나 삭제할 때마다
onQueryChange람다 함수가 호출됩니다. SearchBarDefaults.InputField에는 입력란의 시작 부분에 검색 아이콘을 추가하는leadingIcon과 입력란의 끝에 '추가 옵션' 아이콘을 추가하는trailingIcon이 포함되어 있습니다. 여기에서 사용자에게 정렬 및 필터링 옵션을 제공할 수 있습니다.onSearch = { … }는onSearch람다를 호출하고 검색이 제출될 때 검색창을 축소합니다.LazyColumn은 잠재적으로 많은 검색 결과를 효율적으로 처리합니다.searchResults목록을 반복하고 각 결과를ListItem으로 표시합니다.- 각
ListItem구성 가능한 함수는 항목 텍스트, 추가 정보를 표시하는 텍스트, 별표 아이콘을 항목의leadingContent로 표시합니다. 이 예에서는 항목을 즐겨찾기에 추가하는 옵션이 제공됩니다. - 필터링 로직은 GitHub의 전체
소스 코드에서
CustomizableSearchBarExample를 참고하세요.
결과
추가 리소스
- Material Design: 검색창