The Android Developer Challenge is back! Submit your idea before December 2.

Cómo usar vistas y proveedores de acciones

La biblioteca de compatibilidad de v7 appcompat, Toolbar, proporciona varias formas diferentes para que los usuarios interactúen con tu app. En las lecciones anteriores, se describía cómo definir una acción, que puede ser un botón o un elemento de menú. En esta lección, se describe cómo agregar dos componentes versátiles:

  • Una vista de acción es una acción que proporciona una funcionalidad enriquecida dentro de la barra de la app. Por ejemplo, una vista de acción de búsqueda permite al usuario escribir su texto de búsqueda en la barra de la app, sin tener que cambiar actividades o fragmentos.
  • Un proveedor de acciones es una acción con su propio diseño personalizado. La acción aparece inicialmente como un botón o elemento de menú, pero cuando el usuario hace clic en la acción, el proveedor de acciones controla el comportamiento de la acción de cualquier manera que desees definir. Por ejemplo, el proveedor de acciones puede responder a un clic mostrando un menú.

Las bibliotecas de compatibilidad de Android proporcionan varias vistas de acción especializadas y widgets de proveedor de acciones. Por ejemplo, el widget SearchView implementa una vista de acción para ingresar consultas de búsqueda, y el widget ShareActionProvider implementa un proveedor de acciones para compartir información con otras apps. También puedes definir tus propias vistas de acción y proveedores de acciones.

Cómo agregar una vista de acción

Para agregar una vista de acción, crea un elemento <item> en el recurso de menú de la barra de herramientas, como se describe en Cómo agregar botones de acción. Agrega uno de los dos atributos siguientes al elemento <item>:

  • actionViewClass: Es la clase de un widget que implementa la acción.
  • actionLayout: Es un recurso de diseño que describe los componentes de la acción.

Configura el atributo showAsAction en "ifRoom|collapseActionView" o "never|collapseActionView". La marca collapseActionView indica cómo mostrar el widget cuando el usuario no está interactuando con él: si el widget está en la barra de la app, la app debe mostrar el widget como un ícono. Si el widget está en el Menú ampliado, la app debe mostrar el widget como un elemento de menú. Cuando el usuario interactúa con la vista de acción, se expande para llenar la barra de la app.

Por ejemplo, en el siguiente código, se agrega un widget SearchView a la barra de la app:

    <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" />
    

Si el usuario no está interactuando con el widget, la app muestra el widget como el ícono especificado por android:icon. (Si no hay suficiente espacio en la barra de la app, la app agrega la acción al Menú ampliado). Cuando el usuario presiona el ícono o elemento del menú, se expande el widget para llenar la barra de herramientas, lo que le permite al usuario interactuar con él.

Figura 1: Cuando el usuario hace clic en el ícono de una vista de acción, la IU de la vista llena la barra de herramientas

Si necesitas configurar la acción, hazlo en la devolución de llamada onCreateOptionsMenu() de tu actividad. Puedes obtener la referencia de objeto de la vista de acción si llamas al método getActionView(). Por ejemplo, en el siguiente código, se obtiene la referencia de objeto para el widget SearchView definido en el ejemplo de código anterior:

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)
    }
    

Java

    @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);
    }
    

Cómo responder a la expansión de la vista de acción

Si el elemento <item> la acción tiene una marca collapseActionView, la app muestra la vista de acción como un ícono hasta que el usuario interactúa con la vista de acción. Cuando el usuario hace clic en el ícono, el controlador integrado para onOptionsItemSelected() expande la vista de acción. Si la subclase de tu actividad anula el método onOptionsItemSelected(), tu método de anulación debe llamar a super.onOptionsItemSelected() para que la superclase pueda expandir la vista de acción.

Si quieres realizar una tarea cuando se expande o se contrae la acción, puede definir una clase que implemente MenuItem.OnActionExpandListener y pasar un miembro de esa clase a setOnActionExpandListener(). Por ejemplo, es posible que desees actualizar la actividad en función de si se expande o se contrae una vista de acción. En el siguiente fragmento, se muestra cómo definir y pasar un objeto de escucha:

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
    }
    

Java

    @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;
    }
    

Cómo agregar un proveedor de acciones

Para declarar un proveedor de acciones, crea un elemento <item> en el recurso de menú de la barra de herramientas, como se describe en Cómo agregar botones de acción. Agrega un atributo actionProviderClass y configúralo con el nombre de clase totalmente calificado para la clase de proveedor de acciones.

Por ejemplo, en el siguiente código, se declara un ShareActionProvider, que es un widget definido en la biblioteca de compatibilidad que permite que tu app comparta datos con otras apps:

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

En este caso, no es necesario declarar un ícono para el widget, ya que ShareActionProvider proporciona sus propios gráficos. Si estás usando una acción personalizada, declara un ícono.

Para obtener información sobre cómo crear un proveedor de acciones personalizado, consulta la referencia de ActionProvider. Para obtener información sobre cómo configurar un ShareActionProvider, consulta la referencia para esa clase.