Android

[Android] SearchView 초성 검색(feat. Java)

김한토 2024. 10. 29. 14:31
반응형
SMALL

https://jhb.kr/122

 

 

[Android] 한글 초성 검색

한글 초성 검색 기능이 필요하여 구현해 보았다. 기본 적인 원리는 가~깋 나~닣.......... 하~힣 을 사용 한것. http://www.androidpub.com/45681 를 참조하여 구현하였다. /** * 초성 검색 알고리즘을 위한 클

jhb.kr

참고 자료

 

 

요구 사항

1. searchView 에서 초성 검색이 가능하게 한다. -> 한글자 입력할때마다 필터링

2. 특수문자도 검색

3. x버튼을 누르면 입력 값을 초기화하고 입력값이 없다면 초기화면으로 reset한다.

4. searchIcon과 cursor 색상을 변경한다. 

 

searchSoundUtils.java

/**
 * 초성 검색 알고리즘
 */
public class SoundSearcher {
    private static final char HANGUL_BEGIN_UNICODE = 44032;
    private static final char HANGUL_LAST_UNICODE = 55203;
    private static final int HANGUL_BASE_UNIT = 588;
    private static final char[] INITIAL_SOUNDS = {'ㄱ', 'ㄲ', 'ㄴ', 'ㄷ', 'ㄸ', 'ㄹ', 'ㅁ', 'ㅂ', 'ㅃ', 'ㅅ', 'ㅆ', 'ㅇ', 'ㅈ', 'ㅉ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ'};

    /**
     * 주어진 문자가 초기 자음인지 검사
     *
     * @param sound 검사할 자음
     * @return 초기 자음이면 true, 아니면 false
     */
    private static boolean isInitialSound(char sound) {
        for (char initialSound : INITIAL_SOUNDS) {
            if (initialSound == sound) {
                return true;
            }
        }
        return false;
    }

    /**
     * 주어진 글자의 초성을 반환
     *
     * @param c 검사할 문자
     * @return 초성
     */
    private static char getInitialSound(char c) {
        int index = (c - HANGUL_BEGIN_UNICODE) / HANGUL_BASE_UNIT;
        return INITIAL_SOUNDS[index];
    }

    /**
     * 주어진 문자가 한글인지 검사
     *
     * @param c 문자 하나
     * @return 한글이면 true, 아니면 false
     */
    private static boolean isHangul(char c) {
        return HANGUL_BEGIN_UNICODE <= c && c <= HANGUL_LAST_UNICODE;
    }

    /**
     * 주어진 문자가 특수문자인지 검사
     *
     * @param c 문자
     * @return 특수 문자이면 true, 아니면 false
     */
    private static boolean isSpecialCharacter(char c) {
        return !isHangul(c) && !Character.isLetter(c) && !Character.isDigit(c);
    }

    public SoundSearcher() {
    }

    /**
     * 초성 검색
     *
     * @param value  : 검색 대상 문자열
     * @param search : 검색어 문자열
     * @return 매칭시 true, 아니면 false
     */
    public static boolean matchString(String value, String search) {
        int valueLength = value.length();
        int searchLength = search.length();

        if (searchLength > valueLength) return false;

        for (int i = 0; i <= valueLength - searchLength; i++) {
            int t = 0;
            while (t < searchLength && isMatchingChar(value.charAt(i + t), search.charAt(t))) {
                t++;
            }
            if (t == searchLength) return true;
        }
        return false;
    }

    private static boolean isMatchingChar(char valueChar, char searchChar) {
        if (isInitialSound(searchChar) && isHangul(valueChar)) {
            return getInitialSound(valueChar) == searchChar;
        }
        return (isSpecialCharacter(searchChar) && valueChar == searchChar) || valueChar == searchChar;
    }
}

 

 

1. onQueryTextSubmit(String searchText)
역할: 사용자가 검색 버튼(일반적으로 돋보기 아이콘)을 클릭했을 때 호출.
매개변수: searchText 는 사용자가 입력한 검색어.
사용 예: 이 메서드에서는 검색 결과를 표시하거나, 입력된 검색어를 기반으로 특정 액션을 수행하는 로직을 구현

 

@Override
public boolean onQueryTextSubmit(String searchText) {
    // 검색 버튼 클릭 시의 동작
    searchResults(searchText); 
    return true;
}

 

2. onQueryTextChange(String searchText )
역할: 사용자가 검색어를 입력할 때마다 호출됩니다. 즉, 텍스트가 변경될 때마다 실행
매개변수: searchText 는 현재 입력된 텍스트. 
사용 예: 실시간 검색 결과를 업데이트하거나, 입력된 값에 따라 UI를 동적으로 변경하는 등의 로직을 구현

 

@Override
public boolean onQueryTextChange(String newText) {
    // 입력값이 변경될 때의 동작
    if (newText.equals("")) {
        // 입력값이 없을 때의 처리
    } else {
        updateResults(newText);  // 입력값이 있을 때의 처리
    }
    return true;
}

 

updateResults 함수 예시

 

private void updateResults(String query) {
    // 검색 결과를 저장할 리스트
    List<String> filteredResults = new ArrayList<>();

    // 예시 데이터 (실제 데이터는 데이터베이스나 API에서 가져올 수 있음)
    List<String> allItems = Arrays.asList("Apple", "Banana", "Cherry", "Date", "Fig", "Grape");

    // 입력된 쿼리와 일치하는 항목 필터링
    for (String item : allItems) {
        if (item.toLowerCase().contains(query.toLowerCase())) {
            filteredResults.add(item);
        }
    }

    // UI 업데이트 (예: RecyclerView에 필터링된 결과 표시)
    displayResults(filteredResults);
}

private void displayResults(List<String> results) {
    // RecyclerView 어댑터에 필터링된 결과를 설정
    myAdapter.updateData(results);
    myAdapter.notifyDataSetChanged(); // 데이터 변경 알림
}

 

3. setOnCloseListener
역할: 사용자가 x 버튼을 클릭하여 검색어를 지웠을 때 호출
매개변수: 이 메서드는 OnCloseListener 인터페이스를 구현한 객체를 매개변수로 받음
리턴값: 반환값에 따라 기본 동작(검색어 지우기)이 계속 진행될지, 취소될지가 결정됩니다. true를 반환하면 기본 동작이 취소되고, false를 반환하면 계속 진행됩니다.

searchView.setOnCloseListener(new SearchView.OnCloseListener() {
    @Override
    public boolean onClose() {
        // x 버튼 클릭 시의 동작
        // 추가 이벤트를 여기에 작성
        Toast.makeText(getApplicationContext(), "x 버튼이 눌렸습니다!", Toast.LENGTH_SHORT).show();

        // 기본 동작을 계속 진행하려면 false를 반환
        return false; 
    }
});

 

 

searchView 아이콘 및 커서 색상 바꾸기 

XML파일

            <SearchView
                android:id="@+id/searchView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:theme="@style/mainSearchView"
               />

 

style.xml

<style name="mainSearchView" parent="Widget.AppCompat.SearchView">
        <item name="colorControlActivated">@color/main_color</item>
        <item name="searchIcon">@drawable/icon_search</item>
    </style>

 

search아이콘 변경이 안될시에는 xml파일에 추가해보자

<SearchView
                android:id="@+id/searchView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:theme="@style/mainSearchView"
                android:searchIcon="@drawable/icon_search"/>

 

 

반응형
LIST