Cómo realizar una actividad de presentación animada en Android con ViewPager

08-06-2017 - Andrés Cruz

Cómo realizar una actividad de presentación animada en Android con ViewPager In english

Este material forma parte de mi curso y libro completo; puedes adquirirlos desde el apartado de libros y/o cursos.

Descargar

Las vistas de presentación son un elemento fundamental en cualquier aplicación hoy en día y sobre todo en las aplicaciones móviles en Android ya es una característica común que al momento de instalar la aplicación está presente un sencillo carrusel con sus características viñetas en las cuales se señalan su uso, características, etc y en esta entrada explicaremos como crear una presentación en Android con algunas animaciones empleando el ViewPager el cual es un componente fundamental que ya hemos explicado anteriormente.

Layout: Definiendo la interfaz de nuestro vista de presentación

La vista incluye un par de imágenes que iremos mostrando/ocultando mediante una sencilla animación y esta NO formará parte del ViewPager pero si se irá actualizando dependiendo de la posición en la que se encuentre nuestro carrusel con las imágenes correspondientes:

<FrameLayout
    android:layout_gravity="top"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="88dp">
 
    <ImageView
        android:layout_width="wrap_content"
        android:layout_gravity="center"
        android:layout_height="wrap_content"
        android:id="@+id/icon_image1"
        android:src="@drawable/intro1"/>
 
    <ImageView
        android:layout_width="wrap_content"
        android:layout_gravity="center"
        android:layout_height="wrap_content"
        android:id="@+id/icon_image2"/>
 
</FrameLayout>

Definiremos el ViewPager que nos permite crear el típico carrusel con el contenido (texto en este experimento) que se irá mostrando según el desplazamiento lateral (swipe) del usuario:

<android.support.v4.view.ViewPager
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/intro_view_pager"/>

Por último definiremos las viñetas que se irán actualizando según la posición del ViewPager:

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/bottom_pages"
    android:orientation="horizontal"
    android:layout_gravity="bottom|center_horizontal"
    android:layout_marginBottom="26dp">
 
    <FrameLayout
        android:layout_width="5dp"
        android:layout_height="5dp"
        android:background="#bbbbbb"/>
 
    <FrameLayout
        android:layout_width="5dp"
        android:layout_height="5dp"
        android:background="#bbbbbb"
        android:layout_marginLeft="7dp"/>
 
    <FrameLayout
        android:layout_width="5dp"
        android:layout_height="5dp"
        android:background="#bbbbbb"
        android:layout_marginLeft="7dp"/>
 
    <FrameLayout
        android:layout_width="5dp"
        android:layout_height="5dp"
        android:background="#bbbbbb"
        android:layout_marginLeft="7dp"/>
 
    <FrameLayout
        android:layout_width="5dp"
        android:layout_height="5dp"
        android:background="#bbbbbb"
        android:layout_marginLeft="7dp"/>
 
    <FrameLayout
        android:layout_width="5dp"
        android:layout_height="5dp"
        android:background="#bbbbbb"
        android:layout_marginLeft="7dp"/>
 
    <FrameLayout
        android:layout_width="5dp"
        android:layout_height="5dp"
        android:background="#bbbbbb"
        android:layout_marginLeft="7dp"/>
 
</LinearLayout>

Código Java: armando nuestra vista de presentación y animarla

Finalmente llegamos a la parte crucial y es como empleamos la vista anterior para realizar la presentación animada; primero definiremos los textos, imágenes y títulos de nuestra presentación:

icons = new int[]{
       R.drawable.intro1,
       R.drawable.intro2,
       R.drawable.intro3,
       R.drawable.intro4,
       R.drawable.intro5,
       R.drawable.intro6,
       R.drawable.intro7
};
titles = new int[]{
       R.string.Page1Title,
       R.string.Page2Title,
       R.string.Page3Title,
       R.string.Page4Title,
       R.string.Page5Title,
       R.string.Page6Title,
       R.string.Page7Title
};
messages = new int[]{
       R.string.Page1Message,
       R.string.Page2Message,
       R.string.Page3Message,
       R.string.Page4Message,
       R.string.Page5Message,
       R.string.Page6Message,
       R.string.Page7Message
};

Las imágenes y otros elementos:

topImage1 = (ImageView) findViewById(R.id.icon_image1);
topImage2 = (ImageView) findViewById(R.id.icon_image2);
bottomPages = (ViewGroup) findViewById(R.id.bottom_pages);

Ahora establecemos el evento escuchador del ViewPager que se activará cada vez que se realice un swipe en el ViewPager y validamos que no se esté arrastrando y se encuentre en su posición final:

@Override
public void onPageScrollStateChanged(int i) {
    // la vista no esta siendo arrastrada || La pagina esta en su posicion final
    if (i == ViewPager.SCROLL_STATE_IDLE || i == ViewPager.SCROLL_STATE_SETTLING) {
        if (lastPage != viewPager.getCurrentItem()) {
            lastPage = viewPager.getCurrentItem();
 
            // oculta/muestra una imagen
            final ImageView fadeoutImage;
            final ImageView fadeinImage;
            if (topImage1.getVisibility() == View.VISIBLE) {
                fadeoutImage = topImage1;
                fadeinImage = topImage2;
 
            } else {
                fadeoutImage = topImage2;
                fadeinImage = topImage1;
            }
 
            fadeinImage.bringToFront();
            fadeinImage.setImageResource(icons[lastPage]);
            fadeinImage.clearAnimation();
            fadeoutImage.clearAnimation();
 
            Animation outAnimation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.icon_anim_fade_out);
            outAnimation.setAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {
                }
 
                @Override
                public void onAnimationEnd(Animation animation) {
                    fadeoutImage.setVisibility(View.GONE);
                }
 
                @Override
                public void onAnimationRepeat(Animation animation) {
 
                }
            });
 
            Animation inAnimation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.icon_anim_fade_in);
            inAnimation.setAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {
                    fadeinImage.setVisibility(View.VISIBLE);
                }
 
                @Override
                public void onAnimationEnd(Animation animation) {
                }
 
                @Override
                public void onAnimationRepeat(Animation animation) {
 
                }
            });
 
 
            fadeoutImage.startAnimation(outAnimation);
            fadeinImage.startAnimation(inAnimation);
        }
    }
}
});
}

También aquí se realizan otras funcionalidades como ocultar mostrar la imagen en la cabecera que como indicamos al inicio no forman parte de ViewPager pero si se actualizan conforme el usuario va desplazándose mediante el ViewPager de presentación; las imágenes van ocultándose/mostrandose una por vez y esto se debe para mostrar una sencilla animación al momento de realizar la transición de una imagen a otra; dichas animaciones están definidas incluyendo sus eventos escuchadores e invocadas desde el mismo evento escuchador del ViewPager.

Adaptador del ViewPager para saber la posición de ViewPager en la actividad

Por último definimos un Adapter para nuestro ViewPager el cual nos permitirá colorear las viñetas según la posición en la que nos encontremos y de incrustar (en Android el término se conoce como "inflar") la vista de presentación en nuestro ViewPager:

private class IntroAdapter extends PagerAdapter {
    @Override
    public int getCount() {
        return 7;
    }
 
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        View view = View.inflate(container.getContext(), R.layout.intro_view_layout, NULL);
        TextView headerTextView = (TextView) view.findViewById(R.id.header_text);
        TextView messageTextView = (TextView) view.findViewById(R.id.message_text);
        container.addView(view, 0);
 
        headerTextView.setText(getString(titles[position]));
        messageTextView.setText(getString(messages[position]));
 
        return view;
    }
 
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((View) object);
    }
 
    @Override
    public void setPrimaryItem(ViewGroup container, int position, Object object) {
        super.setPrimaryItem(container, position, object);
        int count = bottomPages.getChildCount();
        for (int a = 0; a < count; a++) {
            View child = bottomPages.getChildAt(a);
            if (a == position) {
                child.setBackgroundColor(0xff2ca5e0);
            } else {
                child.setBackgroundColor(0xffbbbbbb);
            }
        }
    }
 
    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view.equals(object);
    }
 
    @Override
    public void restoreState(Parcelable arg0, ClassLoader arg1) {
    }
 
    @Override
    public Parcelable saveState() {
        return NULL;
    }
 
    @Override
    public void unregisterDataSetObserver(DataSetObserver observer) {
        if (observer != NULL) {
            super.unregisterDataSetObserver(observer);
        }
    }
}

Y esto es todo, con el código anterior podemos tener un fantástica vista de presentación para nuestra aplicación Android bastante modular y personalizable según necesidades la cual la podemos llevar incluso a convertir en una galería de imágenes como veremos en otra ocasión; el código anterior fue obtenido del recurso que corresponde al Telegram.

Puedes descargar el fuente de este experimento al principio y final de esta entrada:

Descargar


Andrés Cruz
Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz en Udemy

Acepto recibir anuncios de interes sobre este Blog.

Conozca nuestros cursos sobre Laravel, CodeIgniter, Flutter, Electron, Django, Flask y muchos más!

Ver los cursos
¡Hazte afiliado en Gumroad!

!Cursos desde!

4$

En Academia

Ver los cursos

!Libros desde!

1$

Ver los libros
!Web Alojada en Hostinger!