Implementar la función como la aplicación de iOS que cierra vertical Desplazar-para-Descartar con ViewPager

Actualmente tengo vistas alineadas horizontalmente en un ViewPager y puedo recorrerlas a través de un PagerAdapter. Actualmente, para realizar la acción que me gustaría hacer en el golpe, tengo que hacer un doble toque en la página de la vista. Podría código postal, pero es un poco difícil extraer las piezas necesarias …

Lo que me gustaría es la posibilidad de deslizar verticalmente en estas vistas, hacer que se traduzcan verticalmente con deslizar y desaparecer, y luego realizar una acción cuando llegan a cierta distancia del borde del dispositivo.

Para tener una idea de lo que estoy pensando, en la aplicación Galería puedes pellizcar una foto abierta para alejar la imagen y abrir una vista de película horizontal. Desde allí puedes desplazarte hacia arriba (o hacia abajo) en una foto o un video para eliminarlo. Para aquellos que no tienen la misma aplicación de Galería, es exactamente como cerrar aplicaciones en iOS.

He intentado escanear el código fuente de la aplicación Galería, pero no encontré la actividad correcta.

view.setOnTouchListener(new View.OnTouchListener(){ public boolean onTouch(View v, MotionEvent motion) { float y = motion.getY(); /* NOTE: the following line might need to be in runOnUiThread() */ view.animate().alpha(1-Math.abs(y-height/2)/(height/2)).setDuration(50).start(); return true; //false if you want to pass this event on to other listeners } }); 

La explicación para usar 1-Math.abs(y-height/2)/(height/2) es que quiero que alfa sea 1 cuando estoy en el centro, y alfa a ser 0 cuando está en la parte superior o inferior . Tienes que determinarte cómo obtienes el valor de height , o si quieres usar un método diferente para calcular el alfa. Si desea obtener la posición táctil relativa a la pantalla en lugar de la posición relativa a la vista, utilice getRawY() .

Además, puede ser útil saber que para ver si MotionEvent es un evento de prensa, arrastrar o liberar, utilice motion.getAction() == con MotionEvent.ACTION_UP, MotionEvent.ACTION_MOVE y MotionEvent.ACTION_DOWN, respectivamente.

Compruebe el código abajo, esto puede ayudarle:

  public class MainActivity extends Activity implements View.OnTouchListener{ private RelativeLayout baseLayout; private int previousFingerPosition = 0; private int baseLayoutPosition = 0; private int defaultViewHeight; private boolean isClosing = false; private boolean isScrollingUp = false; private boolean isScrollingDown = false; @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_popup); baseLayout = (RelativeLayout) findViewById(R.id.base_popup_layout);//this is the main layout baseLayout.setOnTouchListener(this); } public boolean onTouch(View view, MotionEvent event) { // Get finger position on screen final int Y = (int) event.getRawY(); // Switch on motion event type switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: // save default base layout height defaultViewHeight = baseLayout.getHeight(); // Init finger and view position previousFingerPosition = Y; baseLayoutPosition = (int) baseLayout.getY(); break; case MotionEvent.ACTION_UP: // If user was doing a scroll up if(isScrollingUp){ // Reset baselayout position baseLayout.setY(0); // We are not in scrolling up mode anymore isScrollingUp = false; } // If user was doing a scroll down if(isScrollingDown){ // Reset baselayout position baseLayout.setY(0); // Reset base layout size baseLayout.getLayoutParams().height = defaultViewHeight; baseLayout.requestLayout(); // We are not in scrolling down mode anymore isScrollingDown = false; } break; case MotionEvent.ACTION_MOVE: if(!isClosing){ int currentYPosition = (int) baseLayout.getY(); // If we scroll up if(previousFingerPosition >Y){ // First time android rise an event for "up" move if(!isScrollingUp){ isScrollingUp = true; } // Has user scroll down before -> view is smaller than it's default size -> resize it instead of change it position if(baseLayout.getHeight()<defaultViewHeight){ baseLayout.getLayoutParams().height = baseLayout.getHeight() - (Y - previousFingerPosition); baseLayout.requestLayout(); } else { // Has user scroll enough to "auto close" popup ? if ((baseLayoutPosition - currentYPosition) > defaultViewHeight / 4) { closeUpAndDismissDialog(currentYPosition); return true; } // } baseLayout.setY(baseLayout.getY() + (Y - previousFingerPosition)); } // If we scroll down else{ // First time android rise an event for "down" move if(!isScrollingDown){ isScrollingDown = true; } // Has user scroll enough to "auto close" popup ? if (Math.abs(baseLayoutPosition - currentYPosition) > defaultViewHeight / 2) { closeDownAndDismissDialog(currentYPosition); return true; } // Change base layout size and position (must change position because view anchor is top left corner) baseLayout.setY(baseLayout.getY() + (Y - previousFingerPosition)); baseLayout.getLayoutParams().height = baseLayout.getHeight() - (Y - previousFingerPosition); baseLayout.requestLayout(); } // Update position previousFingerPosition = Y; } break; } return true; } } 

Para la animación utilice los siguientes métodos:

  public void closeUpAndDismissDialog(int currentPosition){ isClosing = true; ObjectAnimator positionAnimator = ObjectAnimator.ofFloat(baseLayout, "y", currentPosition, -baseLayout.getHeight()); positionAnimator.setDuration(300); positionAnimator.addListener(new Animator.AnimatorListener() { . . . @Override public void onAnimationEnd(Animator animator) { finish(); } . . . }); positionAnimator.start(); } public void closeDownAndDismissDialog(int currentPosition){ isClosing = true; Display display = getWindowManager().getDefaultDisplay(); Point size = new Point(); display.getSize(size); int screenHeight = size.y; ObjectAnimator positionAnimator = ObjectAnimator.ofFloat(baseLayout, "y", currentPosition, screenHeight+baseLayout.getHeight()); positionAnimator.setDuration(300); positionAnimator.addListener(new Animator.AnimatorListener() { . . . @Override public void onAnimationEnd(Animator animator) { finish(); } . . . }); positionAnimator.start(); } 

Terminé consiguiendo este funcionamiento más-o-menos clonando la biblioteca bien-escrita de Android-SwipeToDismiss y apenas substituyendo el código de ListView con un ViewPager.

El producto terminado se veía así.

resultado final

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