사용자 도구

사이트 도구


android:collection:search
search

문서의 이전 판입니다!


목적

코틀린의 Collection 기능을 이용하여 검색 기능을 만들 것이다.

정렬

List를 정렬하는 것은 SortedBy 함수를 이용한다. 이를 역으로 정렬하려면 뒤에 reversed를 넣으면 된다.

fun quoteList(sortMethod: QuoteSort) : List<QuoteText> {
    return when (sortMethod) {
        QuoteSort.TitleASC -> QuoteData.quoteData.sortedBy { it.title }
        QuoteSort.TitleDESC -> QuoteData.quoteData.sortedBy { it.title }.reversed()
        QuoteSort.AuthorASC -> QuoteData.quoteData.sortedBy { it.author }
        QuoteSort.AuthorDESC -> QuoteData.quoteData.sortedBy { it.author }.reversed()
    }

필터링

1. 전체 소스 코드

fun quoteList(searchString : String, sortMethod: QuoteSort) : List<QuoteText> {
 
    if (searchString != "") {
        return when (sortMethod) {
            QuoteSort.TitleASC -> QuoteData.quoteData.filter { it.title.contains(searchString) || it.author.contains(searchString) || it.quote.first().contains(searchString) }.sortedBy { it.title }
            QuoteSort.TitleDESC -> QuoteData.quoteData.filter { it.title.contains(searchString) || it.author.contains(searchString) || it.quote.first().contains(searchString)}.sortedBy { it.title }.reversed()
            QuoteSort.AuthorASC -> QuoteData.quoteData.filter { it.title.contains(searchString) || it.author.contains(searchString) || it.quote.first().contains(searchString)}.sortedBy { it.author }
            QuoteSort.AuthorDESC -> QuoteData.quoteData.filter { it.title.contains(searchString) || it.author.contains(searchString) || it.quote.first().contains(searchString)}.sortedBy { it.author }.reversed()
        }
    }else
    {
        return when (sortMethod) {
            QuoteSort.TitleASC -> QuoteData.quoteData.sortedBy { it.title }
            QuoteSort.TitleDESC -> QuoteData.quoteData.sortedBy { it.title }.reversed()
            QuoteSort.AuthorASC -> QuoteData.quoteData.sortedBy { it.author }
            QuoteSort.AuthorDESC -> QuoteData.quoteData.sortedBy { it.author }.reversed()
        }
    }
}

2. 검색어가 있을 때에만 필터링

검색어가 없으면 전체리스트를 보여주게 해야 한다.

따라서 searchString != “” 일 때에만 필터링을 하게 했따.

3. 필터

필터는 람다식을 이용하여 중괄호 내에 필터의 기준 값이 들어간다.

우리는 제목, 저자, 그리고 내용 중에 그 어느 곳에서든 검색어가 들어가 있으면 리스트에 포할시킬 것이다. 따라서 그 세개의 기준을 모두 or로 묶어야 한다.

it.title.contains(searchString) || it.author.contains(searchString) || it.quote.first().contains(searchString)

4. 일부 포함으로 변경

필터는 완전일치를 사용할 수도 있다. 이를테면 다음과 같다.

QuoteData.quoteData.filter { it.title == searchString}

그런데 위와 같이 완전 일치를 사용하면 검색의 목적이 훼손된다. 검색이란 일부 단어만으로 쉽게 내가 찾고자 하는 목록이 나와야 하기 떄문이다. 따라서 일부만 포한하더라도 필터링이 되어야 한다.

스트링을 다루는 함수 중 일부포함은 contains함수이다.

따라서 다음과 같이 일부를 포함하는 문자를 즉각 필터링 하게 코드를 짤 수 있다.

QuoteData.quoteData.filter { it.title.contains(searchString) }

5. 대소문자 구분 없이 비교하기

equals함수는 다음과 같이 ignorecase 옵션이 존재하지만,

answerEditText.equals("brasil", ignoreCase = true)

contains함수는 ignorecase가 없다. 따라서 비교할 문장과 참조할 문장을 모두 소문자 혹은 대문자로 강제 변경해주어야 한다.

다음과 같이 소문자로 통일해주면 대소문자 구분 없이 비교가 가능하다.

it.title.lowercase().contains(searchString.lowercase())

컴포즈에서 불러오기

다음과 같이 검색창을 만들고 리스를 불러오면 된다.

var searchString by remember { mutableStateOf("") }
 
Row(modifier = Modifier
.fillMaxWidth()
.padding(6.dp), horizontalArrangement = Arrangement.SpaceEvenly) {
 
OutlinedTextField(
    value =  searchString,
    onValueChange = { searchString = it },
    label = { Text(text = "검색", style = MaterialTheme.typography.titleMedium )  },
    trailingIcon = {
        IconButton(onClick = { /*  */ }) {
            Icon(
                imageVector = Icons.Default.Search,
                contentDescription = "Select Drop Down"
            )
        }
    },
    textStyle = TextStyle(fontFamily = fontkjcMyungjo, fontSize = 14.sp, fontWeight = FontWeight.SemiBold, fontStyle = FontStyle.Normal),
    keyboardOptions = KeyboardOptions.Default,
)
}
 
 
viewModel.quoteList(searchString, sortMethod).forEach() { item ->
 
DocuItemCard(item = item)
 
}
로그인하면 댓글을 남길 수 있습니다.

android/collection/search.1746969732.txt.gz · 마지막으로 수정됨: 2025/05/11 22:22 저자 이거니맨