작업 뷰 및 작업 제공자 사용하기

v7 appcompat 지원 라이브러리 Toolbar에서는 사용자가 앱과 상호작용할 수 있는 다양한 방법을 제공합니다. 이전 과정에서는 작업(버튼이나 메뉴 항목일 수 있음)을 정의하는 방법을 설명했습니다. 이 과정에서는 다음과 같은 다목적 구성요소 2개를 추가하는 방법을 설명합니다.

  • 작업 뷰: 앱바 내에 풍부한 기능을 제공하는 작업입니다. 예를 들어 검색 작업 뷰에서는 활동이나 프래그먼트를 변경할 필요 없이 사용자가 앱바에 검색 텍스트를 입력할 수 있습니다.
  • 작업 제공자: 고유한 맞춤 레이아웃이 사용된 작업입니다. 작업은 처음에 버튼이나 메뉴 항목으로 표시되지만, 사용자가 작업을 클릭하면 개발자가 정의한 방법대로 작업 제공자가 작업의 동작을 제어합니다. 예를 들어 작업 제공자는 클릭에 응답하여 메뉴를 표시할 수 있습니다.

Android 지원 라이브러리는 특수한 작업 뷰 위젯과 작업 제공자 위젯을 여러 개 제공합니다. 예를 들어 SearchView 위젯은 검색어 입력을 위한 작업 뷰를 구현하고 ShareActionProvider 위젯은 다른 앱과 정보를 공유하기 위한 작업 제공자를 구현합니다. 고유한 작업 뷰와 작업 제공자를 정의할 수도 있습니다.

작업 뷰 추가하기

작업 뷰를 추가하려면 작업 버튼 추가하기에 설명된 것처럼 툴바의 메뉴 리소스에 <item> 요소를 만듭니다. 다음 두 속성 중 하나를 <item> 요소에 추가합니다.

  • actionViewClass: 작업을 구현하는 위젯의 클래스입니다.
  • actionLayout: 작업의 구성요소를 설명하는 레이아웃 리소스입니다.

showAsAction 속성을 "ifRoom|collapseActionView" 또는 "never|collapseActionView"로 설정합니다. collapseActionView 플래그는 사용자가 위젯과 상호작용하지 않을 때 위젯을 표시하는 방법을 나타냅니다. 위젯이 앱 바에 있는 경우 앱은 위젯을 아이콘으로 표시해야 합니다. 위젯이 더보기 메뉴에 있는 경우 앱은 위젯을 메뉴 항목으로 표시해야 합니다. 사용자가 작업 뷰와 상호작용할 때는 위젯이 확장되어 앱 바를 채웁니다.

예를 들어 다음 코드는 SearchView 위젯을 앱 바에 추가합니다.

    <item android:id="@+id/action_search"
         android:title="@string/action_search"
         android:icon="@drawable/ic_search"
         app:showAsAction="ifRoom|collapseActionView"
         app:actionViewClass="android.support.v7.widget.SearchView" />
    

사용자가 위젯과 상호작용하지 않는 경우 앱은 위젯을 android:icon에 지정된 아이콘으로 표시합니다. 앱 바의 공간이 충분하지 않은 경우 앱은 작업을 더보기 메뉴에 추가합니다. 사용자가 아이콘이나 메뉴 항목을 탭하면 위젯은 확장되어 툴바를 채우고 사용자가 상호작용할 수 있도록 합니다.

그림 1. 사용자가 작업 뷰의 아이콘을 클릭하면 해당 뷰의 UI가 툴바를 채웁니다.

작업을 구성해야 하는 경우 활동의 onCreateOptionsMenu() 콜백에서 구성하면 됩니다. getActionView() 메서드를 호출하여 작업 뷰의 객체 참조를 가져올 수 있습니다. 예를 들어 다음 코드는 이전 코드 예에서 정의한 SearchView 위젯의 객체 참조를 가져옵니다.

Kotlin

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.main_activity_actions, menu)

        val searchItem = menu?.findItem(R.id.action_search)
        val searchView = searchItem?.actionView as SearchView

        // Configure the search info and add any event listeners...

        return super.onCreateOptionsMenu(menu)
    }
    

자바

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main_activity_actions, menu);

        MenuItem searchItem = menu.findItem(R.id.action_search);
        SearchView searchView =
                (SearchView) searchItem.getActionView();

        // Configure the search info and add any event listeners...

        return super.onCreateOptionsMenu(menu);
    }
    

작업 뷰 확장에 응답하기

작업의 <item> 요소에 collapseActionView 플래그가 있으면 사용자가 작업 뷰와 상호작용할 때까지 앱은 작업 뷰를 아이콘으로 표시합니다. 사용자가 아이콘을 클릭하면 내장된 onOptionsItemSelected() 핸들러가 작업 뷰를 확장합니다. 활동 서브클래스가 onOptionsItemSelected() 메서드를 재정의하는 경우 슈퍼클래스가 작업 뷰를 확장할 수 있도록 재정의 메서드가 super.onOptionsItemSelected()를 호출해야 합니다.

작업 뷰가 확장되거나 축소될 때 어떤 작업을 하려면 MenuItem.OnActionExpandListener를 구현하는 클래스를 정의하여 해당 클래스의 멤버를 setOnActionExpandListener()에 전달합니다. 예를 들어 작업 뷰가 확장되었는지 축소되었는지에 따라 활동을 업데이트해야 하는 경우가 있습니다. 다음 스니펫은 리스너를 정의하고 전달하는 방법을 보여줍니다.

Kotlin

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.options, menu)
        // ...

        // Define the listener
        val expandListener = object : MenuItem.OnActionExpandListener {
            override fun onMenuItemActionCollapse(item: MenuItem): Boolean {
                // Do something when action item collapses
                return true // Return true to collapse action view
            }

            override fun onMenuItemActionExpand(item: MenuItem): Boolean {
                // Do something when expanded
                return true // Return true to expand action view
            }
        }

        // Get the MenuItem for the action item
        val actionMenuItem = menu?.findItem(R.id.myActionItem)

        // Assign the listener to that action item
        actionMenuItem?.setOnActionExpandListener(expandListener)

        // Any other things you have to do when creating the options menu...

        return true
    }
    

자바

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.options, menu);
        // ...

        // Define the listener
        OnActionExpandListener expandListener = new OnActionExpandListener() {
            @Override
            public boolean onMenuItemActionCollapse(MenuItem item) {
                // Do something when action item collapses
                return true;  // Return true to collapse action view
            }

            @Override
            public boolean onMenuItemActionExpand(MenuItem item) {
                // Do something when expanded
                return true;  // Return true to expand action view
            }
        };

        // Get the MenuItem for the action item
        MenuItem actionMenuItem = menu.findItem(R.id.myActionItem);

        // Assign the listener to that action item
        MenuItemCompat.setOnActionExpandListener(actionMenuItem, expandListener);

        // Any other things you have to do when creating the options menu...

        return true;
    }
    

작업 제공자 추가하기

작업 제공자를 선언하려면 작업 버튼 추가하기에 설명된 대로 툴바의 메뉴 리소스에서 <item> 요소를 만듭니다. actionProviderClass 속성을 추가하고 작업 제공자 클래스의 정규화된 클래스 이름으로 설정합니다.

예를 들어 다음 코드는 지원 라이브러리에 정의된 위젯인 ShareActionProvider를 선언합니다. 이 위젯은 앱이 다른 앱과 데이터를 공유하도록 허용합니다.

    <item android:id="@+id/action_share"
        android:title="@string/share"
        app:showAsAction="ifRoom"
        app:actionProviderClass="android.support.v7.widget.ShareActionProvider"/>
    

이 경우 ShareActionProvider가 고유 그래픽을 제공하므로 위젯의 아이콘을 선언할 필요가 없습니다. 맞춤 작업을 사용 중일 때는 아이콘을 선언하세요.

맞춤 작업 제공자 만들기에 관해서는 ActionProvider 참조에서 자세히 확인하세요. ShareActionProvider 구성에 관해서는 이 클래스의 참조에서 자세히 확인하세요.