본문 바로가기

안드로이드 앱 스쿨 2기/Android

[10주차 - 수] ActionView

ActionView

  • ActionBar에 View를 배치하고 이를 접었다 폈다 할 수 있는 개념이다.
  • 주로 검색 기능을 만들 때 사용한다.

 

1. Main_menu 파일 만들기

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/item1"
        android:icon="@android:drawable/ic_menu_search"
        android:title="SearchBar"
        app:showAsAction="always|collapseActionView"
        app:actionViewClass="androidx.appcompat.widget.SearchView"/>
</menu>

app:actionViewClass="androidx.appcompat.widget.SearchView"
  • 이 코드를 추가 시켜주어야,  위에 사진에 있는 것 처럼 돋보기 사진을 클릭 했을 때, 검색 기능이 구현이 된다.

[챗 GPT 설명]

app:actionViewClass="androidx.appcompat.widget.SearchView"는 안드로이드 앱에서 검색 기능을 구현하기 위해 사용되는 XML 속성입니다.

 

androidx.appcompat.widget.SearchView는 AndroidX 라이브러리에서 제공하는 위젯입니다. 이 위젯은 검색 필드와 관련된 기능을 제공하며, 사용자가 텍스트를 입력하여 검색할 수 있도록 해줍니다.

 

app:actionViewClass 속성은 툴바나 액션바와 같은 앱의 액션 뷰 영역에 해당 위젯을 표시하고자 할 때 사용됩니다. 이 속성을 사용하면 해당 위젯이 앱의 액션 뷰로서 동작하며, 검색 필드를 표시하고 검색 기능을 구현할 수 있습니다.

 

2. activity_main.xml

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />

    <TextView
        android:id="@+id/textView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />

    <TextView
        android:id="@+id/textView4"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textAppearance="@style/TextAppearance.AppCompat.Large"/>

    <ListView
        android:id="@+id/list1"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </ListView>
</LinearLayout>

 

3. MainActivity

 

class MainActivity : AppCompatActivity() {

    lateinit var activityMainBinding: ActivityMainBinding

    val data1 = arrayOf(
        "aaaa", "bbbb", "cccc", "aabb", "ccdd"
    )

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        activityMainBinding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(activityMainBinding.root)

        activityMainBinding.run{
            list1.run{
                adapter = ArrayAdapter<String>(
                    this@MainActivity, android.R.layout.simple_list_item_1, data1
                )
                // 리스트 뷰가 검색이 가능하도록 설정한다.
                isTextFilterEnabled = true

                setOnItemClickListener { adapterView, view, i, l ->
                    // 리스트 뷰에서 position 번째 항목의 문자열값을 가져온다.
                    val str1 = adapterView.adapter.getItem(i) as String
                    // 해당 문자열이 몇 번째에 있는지 확인한다.
                    val idx = data1.indexOf(str1)
                    activityMainBinding.textView4.text = data1[idx]
                }

            }
        }

    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {

        menuInflater.inflate(R.menu.main_menu, menu)

        // SearchView를 가지고 있는 MenuItem을 가져온다.
        val item1 = menu?.findItem(R.id.item1)
        // SearchView를 추출한다.
        val searchView = item1?.actionView as SearchView
        // 안내 문구를 설정한다.
        searchView.queryHint = "검색어 입력"

        // ActionView가 펼쳐지거나 접혔을 때...
        item1.setOnActionExpandListener(object : MenuItem.OnActionExpandListener{

            // 펼쳐 졌을 떄
            // true를 반환하면 펼쳐지고 false를 반환하면 펼치지지 않는다.
            override fun onMenuItemActionExpand(item: MenuItem): Boolean {
                activityMainBinding.textView.text = "펼쳐 졌을 때"
                return true
            }

            // 접혔을 때
            // true를 반환하면 펼쳐지고 false를 반환하면 펼치지지 않는다.
            override fun onMenuItemActionCollapse(item: MenuItem): Boolean {
                activityMainBinding.textView.text = "접혀 졌을 때"
                return true
            }

        })

        // SerachView의 리스너
        searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener{

            // 문자열 입력이 완료되었을 때
            override fun onQueryTextSubmit(query: String?): Boolean {
                activityMainBinding.textView2.text = "문자열 입력 완료"
                activityMainBinding.textView3.text = "입력 완료 : $query"
                searchView.clearFocus()

                // 문자열 입력이 완료된 후
                // ActionView를 접어준다.
                item1.collapseActionView()
                // ActionView를 펼쳐준다.
                // item1.expandActionView()

                return true
            }

            // 입력 중에 호출되는 메서드
            override fun onQueryTextChange(newText: String?): Boolean {
                activityMainBinding.textView2.text = "문자열 입력중"
                activityMainBinding.textView3.text = "입력 중 : $newText"

                // ListView에 검색어를 설정한다.
                activityMainBinding.list1.setFilterText(newText)

                if(newText?.length == 0){
                    activityMainBinding.list1.clearTextFilter()
                }

                return true
            }

        })

        return super.onCreateOptionsMenu(menu)
    }

}

 


// 안내 문구를 설정한다.
searchView.queryHint = "검색어 입력"

queryHint는 검색 필드에 표시되는 안내 문구로, 사용자에게 어떤 종류의 검색어를 입력해야 하는지 알려줍니다. 예시에서는 "검색어 입력"이라는 안내 문구를 설정한 것입니다.

 

item1.setOnActionExpandListener(object : MenuItem.OnActionExpandListener{

            // 펼쳐 졌을 떄
            // true를 반환하면 펼쳐지고 false를 반환하면 펼치지지 않는다.
            override fun onMenuItemActionExpand(item: MenuItem): Boolean {
                activityMainBinding.textView.text = "펼쳐 졌을 때"
                return true
            }

            // 접혔을 때
            // true를 반환하면 펼쳐지고 false를 반환하면 펼치지지 않는다.
            override fun onMenuItemActionCollapse(item: MenuItem): Boolean {
                activityMainBinding.textView.text = "접혀 졌을 때"
                return true
            }

        })

 

[챗 GPT 설명]

  1. item1.setOnActionExpandListener(object : MenuItem.OnActionExpandListener { ... }): item1 MenuItem에 대해 OnActionExpandListener를 설정합니다. OnActionExpandListener 액션 뷰가 펼쳐지거나 접혔을 때 발생하는 이벤트를 처리하기 위해 사용됩니다.
  2. override fun onMenuItemActionExpand(item: MenuItem): Boolean { ... }: 액션 뷰가 펼쳐졌을 때 호출되는 메서드입니다. 이 메서드에서는 item 매개변수를 통해 펼쳐진 MenuItem에 접근할 수 있습니다. 예시에서는 "펼쳐 졌을 때"라는 텍스트를 activityMainBinding.textView에 설정하고, true를 반환합니다. true를 반환하면 액션 뷰가 펼쳐지고, false를 반환하면 펼치지 않게 됩니다.
  3. override fun onMenuItemActionCollapse(item: MenuItem): Boolean { ... }: 액션 뷰가 접혀졌을 때 호출되는 메서드입니다. 이 메서드에서도 item 매개변수를 통해 접힌 MenuItem에 접근할 수 있습니다. 예시에서는 "접혀 졌을 때"라는 텍스트를 activityMainBinding.textView에 설정하고, true를 반환합니다. true를 반환하면 액션 뷰가 접히고, false를 반환하면 접히지 않게 됩니다.

이렇게 코드를 사용하면 액션 뷰의 펼침 및 접힘 이벤트를 처리할 수 있습니다. onMenuItemActionExpand 메서드는 액션 뷰가 펼쳐졌을 때 호출되며, onMenuItemActionCollapse 메서드는 액션 뷰가 접혀졌을 때 호출됩니다. 이러한 이벤트 처리를 통해 액션 뷰의 상태 변화에 따라 필요한 동작을 수행할 수 있습니다.

 

 

	// SerachView의 리스너
        searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener{

            // 문자열 입력이 완료되었을 때
            override fun onQueryTextSubmit(query: String?): Boolean {
                activityMainBinding.textView2.text = "문자열 입력 완료"
                activityMainBinding.textView3.text = "입력 완료 : $query"
                searchView.clearFocus()

                // 문자열 입력이 완료된 후
                // ActionView를 접어준다.
                item1.collapseActionView()
                // ActionView를 펼쳐준다.
                // item1.expandActionView()

                return true
            }

            // 입력 중에 호출되는 메서드
            override fun onQueryTextChange(newText: String?): Boolean {
                activityMainBinding.textView2.text = "문자열 입력중"
                activityMainBinding.textView3.text = "입력 중 : $newText"

                // ListView에 검색어를 설정한다.
                activityMainBinding.list1.setFilterText(newText)

                if(newText?.length == 0){
                    activityMainBinding.list1.clearTextFilter()
                }

                return true
            }

        })

 

[챗 GPT 설명]

  1. searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { ... }): SearchView에 대해 OnQueryTextListener를 설정합니다. OnQueryTextListener검색어 입력 이벤트를 처리하기 위해 사용됩니다.
  2. override fun onQueryTextSubmit(query: String?): Boolean { ... }: 검색어 입력이 완료되었을 때 호출되는 메서드입니다. 이 메서드에서는 query 매개변수를 통해 입력된 검색어에 접근할 수 있습니다. 예시에서는 "문자열 입력 완료"라는 텍스트를 activityMainBinding.textView2에 설정하고, 입력된 검색어를 "입력 완료 : $query" 형식으로 activityMainBinding.textView3에 설정합니다. 또한, searchView.clearFocus()를 통해 SearchView의 포커스를 해제하고, item1.collapseActionView()를 통해 액션 뷰를 접는 동작을 수행합니다.
  3. override fun onQueryTextChange(newText: String?): Boolean { ... }: 입력 중에 호출되는 메서드입니다. 이 메서드에서는 newText 매개변수를 통해 입력 중인 검색어에 접근할 수 있습니다. 예시에서는 "문자열 입력중"라는 텍스트를 activityMainBinding.textView2에 설정하고, 입력 중인 검색어를 "입력 중 : $newText" 형식으로 activityMainBinding.textView3에 설정합니다. 또한, activityMainBinding.list1.setFilterText(newText)를 통해 ListView에 검색어를 설정하고, newText?.length == 0 조건문을 사용하여 검색어가 비어있을 경우 ListView의 필터를 해제합니다.

이렇게 코드를 사용하면 SearchView의 입력 이벤트를 처리할 수 있습니다. onQueryTextSubmit 메서드는 검색어 입력이 완료되었을 때 호출되며, onQueryTextChange 메서드는 입력 중에 호출됩니다. 이를 통해 사용자의 검색어 입력에 따라 원하는 동작을 수행할 수 있습니다.

 

 

// 리스트 뷰가 검색이 가능하도록 설정한다.
isTextFilterEnabled = true

[챗 GPT 설명]

isTextFilterEnabled는 ListView의 텍스트 필터링 기능을 활성화하는 속성입니다.

 

ListView는 데이터 목록을 표시하는 뷰 그룹입니다. isTextFilterEnabled 속성을 true로 설정하면 ListView에서 텍스트 필터링을 사용할 수 있습니다. 이는 사용자가 검색어를 입력하면 ListView에서 해당 검색어와 일치하는 항목들만 보여주는 기능입니다.

 

isTextFilterEnabled 속성을 false로 설정하면 텍스트 필터링 기능을 비활성화할 수 있습니다. 이 경우 ListView는 모든 항목을 보여줍니다. 즉, 필터 기능이 없다

 


[결과]

 

 

출처 : 안드로이드 앱스쿨 2기 윤재성 강사님

'안드로이드 앱 스쿨 2기 > Android' 카테고리의 다른 글

[10주차 - 수] AppBarLayout  (0) 2023.07.02
[10주차 - 수] ViewPager2  (0) 2023.07.02
[10주차 - 수] Toolbar  (0) 2023.07.02
[10주차 - 수] ActionBarNavigation  (0) 2023.07.02
[10주차 - 수] ActionBar  (0) 2023.07.02