Android - Youtube처럼 검색화면을 만들어보자. (Kotlin)

업데이트:

  • 연구주제 : Android - Youtube처럼 검색화면을 만들어보자. (Kotlin)
  • 연구목적 : 안드로이드에서의 코틀린 활용
  • 연구일시 : 2020년 03월 18일 09:00~17:00
  • 연구자 : 이재환 ljh951103@naver.com
  • 연구장비 : HP EliteDesk 800 G4 TWR, Kotlin, Android studio, IntelliJ
  • 관련연구 : Java, Android, Kotlin, RecyclerView


서론

유튜브나 기타 앱들에서 검색화면을 들어가본적이 있는가?
요즘은 메인액티비티에서 바로 검색을 입력받고 검색결과를 출력하는 것이 아닌, 검색버튼을 통해 별도의 검색화면으로 이동하는 방법을 많이 활용한다. 그 방법으로 검색화면을 구성해보자.


본론

메인 툴바

우선 툴바의 검색버튼을 통해 검색화면으로 넘어가게 할 것이다.

<!-- 상단바 -->
        <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/appbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#FFFFFF"
            app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/main_toolbar"
                android:layout_width="match_parent"
                android:layout_height="@dimen/top_size"
                android:background="@color/bar"
                android:minHeight="@dimen/top_size"

                android:theme="@style/AppTheme"
                app:contentInsetStart="0dp"
                app:layout_scrollFlags="scroll|enterAlways|snap">

                <ImageView
                    android:layout_width="120dp"
                    android:layout_height="@dimen/top_size"
                    android:paddingTop="5dp"
                    android:paddingBottom="5dp"
                    android:src="@drawable/toolbar_img" />

                <ImageView
                    android:id="@+id/main_camera_button"
                    android:layout_width="@dimen/top_size"
                    android:layout_height="@dimen/top_size"
                    android:layout_gravity="right"
                    android:padding="10dp"
                    android:src="@drawable/ic_camera" />

                <ImageView
                    android:id="@+id/main_search_button"
                    android:layout_width="@dimen/top_size"
                    android:layout_height="@dimen/top_size"
                    android:layout_gravity="right"
                    android:padding="10dp"
                    android:src="@drawable/ic_search" />

            </androidx.appcompat.widget.Toolbar>
        </com.google.android.material.appbar.AppBarLayout>


검색버튼 리스너

val go_search = findViewById(R.id.main_search_button) as ImageView
        go_search.setOnClickListener {
            val intent = Intent(this, SearchView::class.java)
            startActivity(intent)
        }


검색화면 레이아웃

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
    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"
    android:orientation="vertical">

    <!-- 프레임 -->
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/search_recyclerView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    <!-- 상단바 -->
    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appbar3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/search_toolbar"
            android:layout_width="match_parent"
            android:layout_height="@dimen/top_size"
            android:minHeight="@dimen/top_size"
            android:background="@color/bar"
            android:theme="@style/AppTheme"
            app:contentInsetStart="3dp"
            app:layout_scrollFlags="scroll|enterAlways">

            <!-- 뒤로가기 버튼>
            <ImageView
                android:id="@+id/search_back"
                android:layout_width="@dimen/top_photoview"
                android:layout_height="@dimen/top_photoview"
                android:src="@drawable/ic_arrow_back"
                android:layout_marginTop="3dp"
                android:layout_marginBottom="3dp"/>
            <!-->

            <androidx.appcompat.widget.AppCompatSpinner
                android:id="@+id/searchview_spinner"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_marginTop="5dp"
                android:layout_marginBottom="5dp"
                android:entries="@array/search_option_array"/>

            <androidx.appcompat.widget.SearchView
                android:id="@+id/searchview"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginTop="5dp"
                android:layout_marginEnd="5dp"
                android:layout_marginRight="5dp"
                android:layout_marginBottom="5dp"
                android:background="@color/cardview_light_background"
                app:searchHintIcon="@null"
                tools:ignore="PrivateResource" />

        </androidx.appcompat.widget.Toolbar>
    </com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

검색뷰 액티비티

class SearchView: AppCompatActivity() {

    private var thumbnailList = listOf<thumbnailData>()

    private var recyclerAdapter : RecyclerAdapterForder?= null
    var recyclerView: RecyclerView? = null
    private var mLastClickTime: Long = 0

    @RequiresApi(Build.VERSION_CODES.O)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.search_view)

        searchview.queryHint = "WIMMY 검색"
        searchview.onActionViewExpanded()
        searchview.isIconified = false

        dateQuery()
        searchResult()

    }

    private fun setView() {
        recyclerView = findViewById<RecyclerView>(R.id.search_recyclerView)
        recyclerAdapter =
            RecyclerAdapterForder(this, thumbnailList)
            {thumbnailData ->
                if(SystemClock.elapsedRealtime() - mLastClickTime > 1000) {
                    val intent = Intent(this, Main_PhotoView::class.java)
                    intent.putExtra("dir_name", thumbnailData.data)
                    startActivity(intent)
                }
                mLastClickTime = SystemClock.elapsedRealtime()
            }
        recyclerView?.adapter = recyclerAdapter

        val lm = GridLayoutManager(MainActivity(), 3)
        recyclerView?.layoutManager = lm

    }

    private fun setPhotoSize(row : Int, padding : Int) {
        val displayMetrics = DisplayMetrics()
        this.windowManager.defaultDisplay.getMetrics(displayMetrics)

        val width = displayMetrics.widthPixels
        val size = width / row - 2*padding

        recyclerAdapter!!.setPhotoSize(size, padding)
    }

  
    fun dateQuery(){

        searchview_spinner.onItemSelectedListener = object: AdapterView.OnItemSelectedListener {
            override fun onNothingSelected(parent: AdapterView<*>?) {
            }

            override fun onItemSelected(parent: AdapterView<*>?, v: View?, position: Int, id: Long) {
                searchview.isIconified = false
            }
        }

    }

    fun searchResult(){
        searchview.setOnQueryTextListener (object : androidx.appcompat.widget.SearchView.OnQueryTextListener{
            override fun onQueryTextSubmit(query: String?): Boolean {
                thumbnailList = emptyList()
                when(searchview_spinner.selectedItemPosition) {

                    0 -> {
     
                    }   // 태그

                    1 -> {
  
                    }   // 위치

                    2 -> {

                    }   // 이름

                    3 -> {
 
                    }   // 날짜

                }

                if(thumbnailList.size == 0) {
                    Toast.makeText(this@SearchView, "결과가 없어요. 다시 검색해주세요" , Toast.LENGTH_SHORT).show()
                    return true
                }
                setView()
                setPhotoSize(3, 3)
                val imm: InputMethodManager = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager;
                imm.hideSoftInputFromWindow(searchview.getWindowToken(), 0)
                return true
            }

            override fun onQueryTextChange(query: String?): Boolean {
                //mAdapter!!.filter.filter(query)
                return true
            }
        })
    }

}

위의 searchResult()에서 현재 스피너에 따라 값을 출력하도록 입력해주면 된다.


결론

image

다음 상단 돋보기 버튼을 눌러 검색화면으로 이동한다.


image

화면을 이동하면 다음과같이 자동으로 입력받을 수 있게 액티비티가 출력된다.


향후과제


참고자료


Writer: Jae-Hwan Lee

댓글남기기