Aprende Java Aprende Php Aprende C++ Aprende HTML 5 Aprende JavaScript Aprende JSON Aprende MySQL Aprende SQLServer Aprende Visual Basic 6 Aprende PostgreSQL Aprende SQLite Aprende Redis Aprende Kotlin Aprende XML Aprende Linux VSC Aprende Wordpress Aprende Laravel Aprende VueJS Aprende JQuery Aprende Bootstrap Aprende Netbeans Aprende Android
Sigueme en Facebook Sigueme en Twitter Sigueme en Instagram Sigueme en Youtube Sigueme en TikTok Sigueme en Whatsapp
Home / Android / Compartir texto plano con un ShareActionProvider en Android

Compartir texto plano con un ShareActionProvider en Android

Por jc mouse martes, diciembre 2, 2014

Un Action Provider es un elemento que habita en la Action Bar para incrementar la accesibilidad de nuestras aplicaciones. Este View tiene como fin recibir eventos del usuario como si se tratase de un action button , pero con un alcance más complejo como el despliegue de menús y otros widgets.

Share action

Aunque podemos crear nuestros propios Action Providers, este articulo cubre el uso de un tipo ya prefabricado, llamado ShareActionProvider.

Qué es un ShareActionProvider en Android

La función de esta clase es proveer a la aplicación de una opción para compartir el contenido de nuestra aplicación. Frecuentemente se suele ubicar en las galerías de imágenes y así enviarlas a otras personas por diferentes servicios como Bluetooth, Mensajería, Google+, Facebook, Twitter, etc.

sharing

Para comprender como implementar uno de estos crearemos el siguiente ejemplo:

Ejemplo de un ShareActionProvider

Este ejemplo se le ha denominado «Joky» y su objetivo es permitir compartir a través de un ShareActionProvider chistes que se encuentran predefinidos en la aplicación. Puedes descargar el código completo del proyecto desde aquí:

Descargar Código

A continuación se muestran los pasos a seguir para implementar la aplicación.

Paso 1: Crear un nuevo proyecto en blanco.

Lo primero es crear un nuevo proyecto en blanco con una actividad principal llamada Main.java y su respectivo archivo de diseño activity_main.xml. También es necesario añadir una dependencia de la librería de soporte v4.

Paso 2: Declarar el Action Provider en la Action Bar

Abre el menu con el cual inflarás la Action Bar de la actividad (si se ha generado automáticamente se llamará menu_main.xml) y luego declara un elemento tipo <item>. Para indicar que este item será inflado con un ShareActionProvider, debes usar el atributo support:actionViewclass y asignar la ubicación de la clase en la librería de soporte v7:

//Archivo menu_main.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:support="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/menu_share"
        android:title="@string/menu_share"
        support:actionProviderClass="android.support.v7.widget.ShareActionProvider"
        support:showAsAction="always" />

</menu>

Ahora, si quieres manipular el ShareActionProvider a través de toda la actividad, declara una instancia global dentro de Main:

// Referencia global del ShareActionProvider
private ShareActionProvider shareAP;

Paso 3: Añadir un ViewPager para efecto deslizante

Para la navegación usaremos un ViewPager que permita al usuario deslizar la visualización entre elementos. Así que reemplaza el contenido predeterminado de activity_main.xml por un layout que contenga un nodo raíz de tipo <android.support.v4.view.ViewPager>. Veamos:

// Archivo activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

Paso 4: Crear un Origen de datos para alimentar el Adaptador del ViewPager

Recuerda que un ViewPager necesita un PagerAdapter para poblar sus items. En la aplicación Joky cada uno de estos items será un TextView. Su contenido se obtendrá de 5 cadenas guardadas en el archivo strings.xml.

// Arhivo strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Joky</string>
    <string name="menu_share">Compartir</string>

    <string name="joke1">
        - ¡Maestra! ¡Un niño se ha caído de la ventana!\n
        - ¡Qué horror!!!!? Se dice "por la ventana"
    </string>
    <string name="joke2">
        - Mamá, ¿qué haces en frente de la computadora con los ojos cerrados?\n
        - Nada, hijo, es que Windows me dijo que cerrara las pestañas?</string>
    <string name="joke3">
        - Papá, ¿qué se siente tener un hijo tan guapo?\n
        - No sé hijo, pregúntale a tu abuelo?
    </string>
    <string name="joke4">
        - Mamá, mamá, en el colegio me dicen champú\
        - Tranquilo, Johnson, no más lágrimas.
    </string>
    <string name="joke5">
        - Capitán, ¿Puedo desembarcar por la izquierda?\n
        ? Se dice por babor?\n
        ? Por babor Capitán, ¿Puedo desembarcar por la izquierda?
    </string>
</resources>

Para representar la asociación de cada item a las cadenas, simplemente creas una nueva clase que enfrasque estas características. Dicha clase se llamará ContentItem y tendrá como atributo el identificador del string y un método para compartir su contenido.

Veamos:

// Archivo ContentItem.java
public class ContentItem {

    public final int idString;

    public ContentItem(int idString) {
        this.idString = idString;
    }

    public Intent getShareIntent(Context context) {

        Intent intent = new Intent(Intent.ACTION_SEND);

        intent.setType("text/plain");

        intent.putExtra(Intent.EXTRA_TEXT, context.getString(idString));

        return intent;
    }

}

Retomemos. El propósito de Joky es enviar chistes hacia otras aplicaciones capaces de compartirlos. Tu ya sabes que este tipo de comunicación entre actividades se genera a través de Intents (Lee también Comunicar Actividades a través de Intents).

El método getShareIntent() fabrica el Intent de envío de cada string en nuestro ViewPager. Por esta razón el método retorna en un tipo Intent. Al crear el item se usa la acción ACTION_SEND para indicar que será un intent implícito que congregará aplicaciones de envío de datos.

Luego se indica que enviaremos texto plano («text/plain») y finalmente se incluye un valor extra marcado con la clave EXTRA_TEXT. Esta clave representa la estructura de la cadena y debe enviarse junto al valor que se obtiene con getString() de la clase Context (se recibe una instancia como parámetro).

Lo siguiente es crear una lista de ContentItems dentro de Main para poblar el View Pager:

private final ArrayList items = getContent();

Si notas, se usa el método getContent() para la inicialización de los elementos:

/*
Método para inicializar la lista de items
 */
static ArrayList getContent() {
    ArrayList items = new ArrayList();

    items.add(new ContentItem(R.string.joke1));
    items.add(new ContentItem(R.string.joke2));
    items.add(new ContentItem(R.string.joke3));
    items.add(new ContentItem(R.string.joke4));
    items.add(new ContentItem(R.string.joke5));

    return items;
}

Paso 5: Declarar un PagerAdapter personalizado para el ViewPager

Al querer mostrar cada chiste en una página individual del ViewPager es necesario sobrescribir la clase PagerAdapter para que infle Text Views que ocupen el contenido.

Así que lo primero que tienes que hacer es diseñar el layout para los items del pager:

// Archivo item_text.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    android:textAppearance="?android:textAppearanceMedium"
    android:lineSpacingMultiplier="1.1"
    android:gravity="center_vertical" />

Como ves, cada item es un elemento <TextView> como nodo raíz.

Ahora procedemos a crear una clase anónima dentro de Main para el PagerAdapter:

/*
Adaptador del ViewPager
 */
private final PagerAdapter adapter = new PagerAdapter() {
        LayoutInflater inflater;

        @Override
        public int getCount() {
            return items.size();
        }

        @Override
        public boolean isViewFromObject(View view, Object o) {
            return view == o;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            // Remover item
            container.removeView((View) object);
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            // Evitar infladas de más
            if (inflater == null) {
                inflater = LayoutInflater.from(Main.this);
            }
            // Obtener item actual
            final ContentItem item = items.get(position);

            // Inflar el item con item.text.xml
            TextView tv = (TextView) inflater
                    .inflate(R.layout.item_text, container, false);

            // Asignar la cadena correspondiente
            tv.setText(item.idString);

            // Añadir View al Pager
            container.addView(tv);
            return tv;
        }
    };

Si ya antes has implementado tu propio PagerAdapter sabes que tenemos una extensión realmente sencilla. La verdadera magia está en el método instantiateItem(), el cual infla todas los elementos con el layout item_text.xml y setea el contenido de los Text Views con el método setText() que recibe el identificador de la cadena.

Paso 6: Implementar los eventos con OnPageChangeListener

Cada que un elemento de la lista es seleccionado en el ViewPager se debe actualizar el contenido que se va a enviar. Esto quiere decir que debemos realizar toda nuestra acción en el método onPageSelected(). El ShareActionProvider activa su comportamiento cuando le asignamos una instancia del Intent que contiene la información a trasmitir con el método setShareIntent().

Por esta razón obtendremos el elemento del viewpager seleccionado y retornaremos en su intent con el método getShareIntent().

/*
Escucha del ViewPager
 */
private final ViewPager.OnPageChangeListener listener
        = new ViewPager.OnPageChangeListener() {

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        // Nada por hacer
    }

    @Override
    public void onPageSelected(int position) {

        if (shareAP != null) {
            // Obtener el item actual y su Intent para envío
            ContentItem item = items.get(position);
            Intent shareIntent = item.getShareIntent();

            // Actualizar el shareAP con el intent de envío
            shareAP.setShareIntent(shareIntent);
        }

    }

    @Override
    public void onPageScrollStateChanged(int state) {
        // Nada por hacer
    }
};

La implementación del menú desplegable y los eventos de clics sobre cada opción del provider, no se tienen que implementar, así que despreocupate por la sobrescritura del método onOptionsItemSelected() para la action bar y la implementación del menú.

Paso 7: Implementar el método onCreate() de la actividad principal

El siguiente paso es inflar la actividad principal y obtener una instancia del ViewPager para relacionarle su adaptador y escucha.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Inflar actividad
    setContentView(R.layout.activity_main);

    // Obtener instancia del viewpager
    ViewPager vp = (ViewPager) findViewById(R.id.viewpager);

    // Relacionar escucha
    vp.setOnPageChangeListener(listener);

    // Relacionar adaptador
    vp.setAdapter(adapter);
}

Y por ultimo debes obtener la instancia del ShareActionProvider en el método onCreateOptionsMenu(). También aprovecha para inicializar por defecto el primero elemento del ViewPager, es decir, preasignarle el primer intent que contenga los datos del primer chiste. Veamos:

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflar la action bar
        getMenuInflater().inflate(R.menu.menu_main, menu);

        // Obtener el item que contiene el share action provider
        MenuItem shareItem = menu.findItem(R.id.menu_share);

        // Copiar la referencia del objeto ShareActionProvider del item
        shareAP = (ShareActionProvider) MenuItemCompat.getActionProvider(shareItem);

        // Establecer por defecto el elemento 0 del viewpager
        // para inicializar su share action provider
        ContentItem item = items.get(0);
        Intent shareIntent = item.getShareIntent();
        shareAP.setShareIntent(shareIntent);

        return super.onCreateOptionsMenu(menu);
    }

Si no declaras por defecto el primer elemento que se va a inflar , entonces el ShareActionProvider no mostrará ninguna respuesta ante el usuario a menos que vayas a el segundo item y te devuelvas.

Y ya para finalizar este tutorial, ejecuta y prueba tu aplicación Joky:

Sharing android

Autor: James Revelo
Web: http://www.hermosaprogramacion.com/

Tags

Artículos similares

Crear y mover objetos en tiempo de ejecución

Dando respuesta a una interrogante sobre el como crear objetos en tiempo de ejecución y como manipular estos, desarrolle[...]

Compresión y descompresión de archivos con GZIP

En este post veremos un ejemplo de como comprimir y descomprimir archivos con el método de compresión GZIP  y el pa[...]

Graficos estadisticos con javafx y swing

En este post aprenderemos a usar los gráficos 2d que viene con JavaFX en nuestras aplicaciones java swing. Esto puede se[...]

Rompecabezas [Código Fuente]

Hace tiempo me pidieron el código fuente de un juego de Puzzle de Neon Genesis Evangelión, este juego es completo, tiene[...]

Renombrar atributos JSON con GSON

Si quieres cambiar el nombre de tus atributos sin tener que reescribir código java por X o Y razón, GSON te permite reno[...]

JTable con JCheckBox y celdas NULL

Me llego la siguiente duda por facebook que me pareció interesante: «Se quiere desarrollar una tabla en java que haga us[...]