android:collection:search
search
차이
문서의 선택한 두 판 사이의 차이를 보여줍니다.
다음 판 | 이전 판 | ||
android:collection:search [2025/05/11 21:07] – 만듦 이거니맨 | android:collection:search [2025/05/12 00:27] (현재) – 검색 결과 하이라이트 이거니맨 | ||
---|---|---|---|
줄 82: | 줄 82: | ||
</ | </ | ||
+ | ==== 5. 대소문자 구분 없이 비교하기 ==== | ||
+ | === 가. 한쪽으로 통일해 주는 방법 === | ||
+ | 다음과 같이 소문자로 통일해주면 대소문자 구분 없이 비교가 가능하다. | ||
+ | <code kotlin> | ||
+ | it.title.lowercase().contains(searchString.lowercase()) | ||
+ | </ | ||
+ | |||
+ | === 나. ignoreCase 옵션 === | ||
+ | |||
+ | 과거에는 contains함수에 ignoreCase 옵션이 없었다. 그런데 최신 kotlin문법은 이게 가능하다. | ||
+ | |||
+ | 따라서 다음과 같이 코드가 가능하다. | ||
+ | |||
+ | <code kotlin> | ||
+ | it.title.contains(searchString, | ||
+ | </ | ||
+ | |||
+ | ===== 컴포즈에서 불러오기 ===== | ||
+ | |||
+ | ==== 1. 검색 창 만들기 ==== | ||
+ | |||
+ | |||
+ | 다음과 같이 검색창을 만들고 리스를 불러오면 된다. | ||
+ | |||
+ | <code kotlin> | ||
+ | var searchString by remember { mutableStateOf("" | ||
+ | | ||
+ | Row(modifier = Modifier | ||
+ | .fillMaxWidth() | ||
+ | .padding(6.dp), | ||
+ | |||
+ | OutlinedTextField( | ||
+ | value = searchString, | ||
+ | onValueChange = { searchString = it }, | ||
+ | label = { Text(text = " | ||
+ | trailingIcon = { | ||
+ | IconButton(onClick = {searchString = "" | ||
+ | Icon( | ||
+ | imageVector = Icons.Default.Search, | ||
+ | contentDescription = " | ||
+ | ) | ||
+ | } | ||
+ | }, | ||
+ | textStyle = TextStyle(fontFamily = fontkjcMyungjo, | ||
+ | keyboardOptions = KeyboardOptions.Default, | ||
+ | ) | ||
+ | } | ||
+ | | ||
+ | |||
+ | viewModel.quoteList(searchString, | ||
+ | |||
+ | DocuItemCard(item = item) | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | </ | ||
+ | |||
+ | ==== 2. 검색결과를 하이라이트 하게 해주는 코드 만들기 ==== | ||
+ | |||
+ | 다음과 같이 특정 문구를 하이라이트 하게 해주는 함수를 만들었다. | ||
+ | |||
+ | <code kotlin> | ||
+ | // 검색 결과 하이라이트 | ||
+ | fun highlightContainedText(inputText: | ||
+ | { | ||
+ | |||
+ | val originalString : AnnotatedString = buildAnnotatedString { append(inputText) } | ||
+ | |||
+ | if (inputText.contains(divider, | ||
+ | |||
+ | val listOfString = inputText.split(divider, | ||
+ | |||
+ | val formattedString = buildAnnotatedString { | ||
+ | for (i : Int in 0 until (listOfString.size * 2) -1) | ||
+ | { | ||
+ | if (i % 2 == 0) { | ||
+ | append(listOfString[i/ | ||
+ | }else | ||
+ | { | ||
+ | withStyle(SpanStyle(color = Color.DarkGray, | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | return formattedString | ||
+ | } | ||
+ | |||
+ | return originalString | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | ==== 3. 하이라이트를 포함한 리스트 아이템 소스 ==== | ||
+ | |||
+ | <code kotlin> | ||
+ | // 연락처 목록을 보여주는 컴퍼저블 | ||
+ | @Composable | ||
+ | fun DocuItemCard(item : QuoteText, searchString : String) { | ||
+ | |||
+ | val scope = rememberCoroutineScope() | ||
+ | |||
+ | Row (modifier = Modifier | ||
+ | .fillMaxWidth() | ||
+ | .padding(8.dp) | ||
+ | .background(MaterialTheme.colorScheme.primary, | ||
+ | .padding(10.dp), | ||
+ | verticalAlignment = Alignment.CenterVertically, | ||
+ | |||
+ | ) { | ||
+ | |||
+ | Column (modifier = Modifier | ||
+ | .weight(0.8f) | ||
+ | .padding(horizontal = 16.dp), verticalArrangement = Arrangement.SpaceBetween){ | ||
+ | Text(text = highlightContainedText(item.title, | ||
+ | // Text(text = item.title, color = MaterialTheme.colorScheme.primaryContainer, | ||
+ | Text(text = "by ${highlightContainedText(item.author, | ||
+ | .fillMaxWidth() | ||
+ | .padding(vertical = 4.dp), overflow = TextOverflow.Ellipsis) | ||
+ | Text(text = highlightContainedText(item.quote.first(), | ||
+ | } | ||
+ | |||
+ | IconButton(onClick = { | ||
+ | |||
+ | // 스크린 라우팅하기 | ||
+ | scope.launch { ScreenRouter.navigateTo(Screen.SpeechToText, | ||
+ | }) { | ||
+ | Icon(Icons.Default.Edit, | ||
+ | |||
+ | } | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </ |
android/collection/search.1746965243.txt.gz · 마지막으로 수정됨: 2025/05/11 21:07 저자 이거니맨