Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


OnPageChangeListener alpha crossfading

Hay un montón de preguntas con respecto a crossfading en Android, pero todos ellos incluyen animaciones. Mi pregunta es sobre el crossfading usando el OnPageChangeListener de un ViewPager.

Tengo un ViewPager que podría tener un número ilimitado de vistas, pero en la práctica utiliza cerca de 6 o 7 puntos de vista. No hay mucho que hacer allí.

Cada vista en el ViewPager tiene un mapa de bits de fondo que debe ser fijo y fundido cruzado con el fondo de la vista siguiente (o anterior) en lugar de desplazarse junto con el resto de la vista.

Para lograr esto, desacoplé los fondos y los agregue a una ArrayList y los asigno a ImageViews más tarde. Pero ya que no quiero arriesgarme a la posibilidad de que mi Actividad termine con numerosos ImageViews pensé en la siguiente estructura:

<FrameLayout android:id="@+id/backgroundContainer" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/bottomImage" android:layout_height="match_parent" android:layout_width="match_parent" android:scaleType="center" /> <ImageView android:id="@+id/middleImage" android:layout_height="match_parent" android:layout_width="match_parent" android:scaleType="center" /> <ImageView android:id="@+id/topImage" android:layout_height="match_parent" android:layout_width="match_parent" android:scaleType="center" /> </FrameLayout> 

A OnPageChangeListener se asigna un OnPageChangeListener al ViewPager para asignar los fondos a ImageViews.

 @Override public void onPageSelected(int position) { MyLog.i(TAG, "PAGE SELECTED: " + position); if(position == 0) { _bottomBackground.setImageBitmap(null); _topBackground.setImageBitmap(_backgroundStack.get(position+1)); } else if (position == NUM_ITEMS-1) { _bottomBackground.setImageBitmap(_backgroundStack.get(position-1)); _topBackground.setImageBitmap(null); } else { _bottomBackground.setImageBitmap(_backgroundStack.get(position-1)); _topBackground.setImageBitmap(_backgroundStack.get(position+1)); } _middleBackground.setImageBitmap(_backgroundStack.get(position)); // Make the top front background transparent _topBackground.setAlpha(0f); _currentBackgroundPosition = position; } 

Esto funciona bien si me hubiera gustado sólo cambiar los fondos. Quiero que los fondos se desvanezcan entre sí mientras el usuario pasa el ViewPager. Tengo el fundido para un desplazamiento hacia delante funcionando, pero no entiendo por qué el desvanecimiento para el desplazamiento hacia atrás de alguna manera no da un buen resultado. Durante un desplazamiento hacia atrás, el fondo central debe desvanecerse en el fondo inferior.

Me temo que me estoy perdiendo algo. Nunca cambio el alfa del fondo inferior, pero los resultados del registro siempre muestran el mismo valor para getAlpha() que para el fondo medio.

 @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { if(_currentBackgroundPosition == position) { // scroll forward _topBackground.setAlpha(positionOffset) } else { //scroll backward _middleBackground.setAlpha(positionOffset); } MyLog.i(TAG, "Bottom BackgroundAlpha: " + _bottomBackground.getAlpha()); MyLog.i(TAG, "Middle BackgroundAlpha: " + _middleBackground.getAlpha()); MyLog.i(TAG, "Top BackgroundAlpha: " + _topBackground.getAlpha()); } 

¡Y espera! Hay una cosa más que realmente no soy capaz de averiguar cómo arreglar. Aunque el desvanecimiento de desplazamiento hacia delante está funcionando. Hay un parpadeo súper corto en el fondo. Supongo que esto está sucediendo por la forma en que configuré el método onPageSelected .

¿Existe otra manera de cómo puedo crear / corregir este comportamiento?

  • Cómo configurar el color de un borde de desvanecimiento Android ScrollView?
  • ¿Cómo configurar las imágenes para ScrollView en lugar de degradar los bordes?
  • One Solution collect form web for “OnPageChangeListener alpha crossfading”

    ViewPager.PageTransformer es tu amigo. Voy a tomar un enfoque diferente a lo que intentó, pero resulta en lo que entiendo a la cama de su resultado deseado – deslizamiento izquierda / derecha barridos el contenido, pero se desvanece entre dos imágenes de fondo que no se mueven.

    Cada Fragment en el ViewPager tendrá un diseño como el siguiente:

     <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/image_view" android:layout_height="match_parent" android:layout_width="match_parent" android:scaleType="center" /> <LinearLayout android:id="@+id/content_area" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- content goes here --> </LinearLayout> </FrameLayout> 

    Y se creará un PageTransformer que manipula el diseño dependiendo de la posición que ha sido swiped:

     public class CustomPageTransformer implements ViewPager.PageTransformer { public void transformPage(View view, float position) { int pageWidth = view.getWidth(); View imageView = view.findViewById(R.id.image_view); View contentView = view.findViewById(R.id.content_area); if (position < -1) { // [-Infinity,-1) // This page is way off-screen to the left } else if (position <= 0) { // [-1,0] // This page is moving out to the left // Counteract the default swipe view.setTranslationX(pageWidth * -position); if (contentView != null) { // But swipe the contentView contentView.setTranslationX(pageWidth * position); } if (imageView != null) { // Fade the image in imageView.setAlpha(1 + position); } } else if (position <= 1) { // (0,1] // This page is moving in from the right // Counteract the default swipe view.setTranslationX(pageWidth * -position); if (contentView != null) { // But swipe the contentView contentView.setTranslationX(pageWidth * position); } if (imageView != null) { // Fade the image out imageView.setAlpha(1 - position); } } else { // (1,+Infinity] // This page is way off-screen to the right } } } 

    Y finalmente conectar este PageTransformer a tu ViewPager :

     mViewPager.setPageTransformer(true, new CustomPageTransformer()); 

    Lo he probado en una aplicación existente y funciona bien siempre y cuando los diseños de los fragmentos tengan un fondo transparente.

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.