Android

[Android] SearchView 대신에 EditText 사용하기

도우 2024. 2. 13. 15:18
728x90

위의 돋보기 버튼을 클릭하면
이렇게 바뀌도록 구현해보자

 

Android Studio에는 SearchView가 존재한다. 주로 검색 기능을 제공하는 데 사용되며, 검색 관련 기능을 내장하고 있다.
검색어 제안, 검색 기록, 음성 검색 등의 기능을 손쉽게 구현할 수 있으며 onQueryTextListener를 제공하여 검색 로직도 쉽게 구현할 수 있다.

하지만 원하는 대로 커스텀 하기 불편하기 때문에 EditText를 이용해서 구현해보자.

 

1. 기본 레이아웃 구성

ConstraintLayout 안에 이미지뷰와 텍스트뷰를 생성한다.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/titlebar_layout"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:background="@color/title_bar"
        app:layout_constraintTop_toTopOf="parent"
        tools:layout_editor_absoluteX="1dp">

        <ImageView
            android:id="@+id/iv_logo"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_marginStart="10dp"
            android:layout_marginTop="10dp"
            android:layout_marginBottom="10dp"
            android:background="@color/black"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:srcCompat="@drawable/ic_news_logo" />

        <TextView
            android:id="@+id/tv_news"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="10dp"
            android:layout_marginTop="15dp"
            android:gravity="center"
            android:text="뉴스"
            android:textColor="@color/white"
            android:textSize="22dp"
            app:layout_constraintStart_toEndOf="@+id/iv_logo"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/tv_sport"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="10dp"
            android:layout_marginTop="20dp"
            android:gravity="center"
            android:text="스포츠"
            android:textColor="@color/white"
            android:textSize="16dp"
            app:layout_constraintStart_toEndOf="@+id/tv_enter"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/tv_enter"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="15dp"
            android:layout_marginTop="20dp"
            android:gravity="center"
            android:text="연예"
            android:textColor="@color/white"
            android:textSize="16dp"
            app:layout_constraintStart_toEndOf="@+id/tv_news"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/tv_game"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="10dp"
            android:layout_marginTop="20dp"
            android:gravity="center"
            android:text="게임"
            android:textColor="@color/white"
            android:textSize="16dp"
            app:layout_constraintStart_toEndOf="@+id/tv_sport"
            app:layout_constraintTop_toTopOf="parent" />
        
        <Button
            android:id="@+id/btn_login"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="5dp"
            android:layout_weight="1"
            android:text="로그인"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>

    <View
        android:id="@+id/view"
        android:layout_width="match_parent"
        android:layout_height="3dp"
        android:background="#009688"
        app:layout_constraintTop_toBottomOf="@+id/titlebar_layout"
        tools:layout_editor_absoluteX="16dp" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

2. 검색 레이아웃 추가

검색 기능 구현을 위한 새로운 ConstraintLayout을 titlebar_layout 아래에 추가한다.

<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/search_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="10dp"
    app:layout_constraintTop_toBottomOf="@+id/view">

    <ImageView
        android:id="@+id/back_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@android:drawable/ic_search_delete" 
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:visibility="gone"/>

    <EditText
        android:id="@+id/search_edit_text"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:hint="검색어 입력"
        app:layout_constraintStart_toEndOf="@+id/back_button"
        app:layout_constraintEnd_toStartOf="@+id/search_icon"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

    <ImageView
        android:id="@+id/search_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@android:drawable/ic_search_category_default"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

 

3. 검색 뷰 가시성 설정

현재 titlebar_layout 아래에 검색창이 동시에 존재할 것이다. 우리는 세 가지 상황을 고려해야한다.

1) 기본 상태 
검색창의 visibility = "gone"

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/search_layout"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:padding="10dp"
        android:visibility="gone" // 1) 기본 상태 설정
        app:layout_constraintTop_toBottomOf="@+id/view"
        tools:ignore="UnknownId">

 

2) 검색 버튼(돋보기)를 클릭 했을 때
타이틀바의 visibility = "gone"
검색창의 visibility = "visible"

3) 검색 창의 뒤로가기 버튼을 클릭 했을 때
타이틀바의 visibility = "visible"
검색창의 visibility = "gone"

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        searchLayout = findViewById(R.id.search_layout);
        titleBarLayout = findViewById(R.id.titlebar_layout);
        searchIcon = findViewById(R.id.iv_search);
        backButton = findViewById(R.id.btn_input_delete);

        // 2) 검색 아이콘 클릭 이벤트 처리
        searchIcon.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // titlebar_layout을 숨기고 search_layout을 보이게 함
                titleBarLayout.setVisibility(View.GONE);
                searchLayout.setVisibility(View.VISIBLE);
                updateViewLineConstraint(R.id.search_layout); 
                // view_line을 검색창 아래에 두기
            }
        });

        // 3) 뒤로 가기 버튼 클릭 이벤트 처리
        backButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 검색 레이아웃을 숨기고 titlebar_layout을 다시 보이게 함
                searchLayout.setVisibility(View.GONE);
                titleBarLayout.setVisibility(View.VISIBLE);
                updateViewLineConstraint(R.id.titlebar_layout); 
                // view_line 타이틀바 아래에 위치
            }
        });
    }

 

또한 초록색 라인을 나타내는 view_line은 검색창이 없을 경우에는 타이틀바 아래에 위치, 있을 경우에는 검색창 아래에 위치시키도록 한다.

EditText의 밑줄을 제거하는 방법은 EditText의 android:background 속성을 다음과 같이 설정한다.
android:background="@android:color/transparent"

 

 

구현 결과

 

728x90