PDA

Ver la Versión Completa : [ SOLUCIONADO ] ViewFlipper onTouch()


androizado
04/03/15, 14:32:49
Buenas quería hacer una pregunta respecto al elemento ViewFlipper:

He implementando esté elemento para hacer un pase de imágenes. Todo está bien y lo hace correcto, pero encuentro un detalle cuando quiero pasar con el dedo.

Tengo implementado el siguiente método:


mViewFlipper.setOnTouchListener(new View.OnTouchListener() {
@override (http://www.htcmania.com/member.php?u=42589)
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction())
{
case MotionEvent.ACTION_DOWN:
lastX = motionEvent.getX();
return false;
case MotionEvent.ACTION_UP:
float currentX = motionEvent.getX();
if(lastX < currentX){
mViewFlipper.showPrevious();
}else if (lastX > currentX){
mViewFlipper.showNext();
}
return true;
}
return false;
});Detecto que coge alguna veces el evento ACTION_MOVE o ACTION_CANCEL y no hace el pase porque no detecta el ACTION_UP. ¿Preguntaba si esto es posible correguirlo, o supongo que los eventos es cuestión de cual detecte el móvil?

Decir que el viewFlipper lo tengo dentro de un ScrollView. Y por eso cuando detecta de hacer scroll no me hace el pase hacía la derecha o izquierda.

Gracias de antemano.

Os pongo la Solución

No he podido hacer el repositorio, a si que os dejo esto y espero que os sirva a todos los que necesitéis hacer algo parecido.

Primeramente en nuestro xml definiremos el ViewFlipper dentro de un ScrollView:

Yo a este archivo lo he llamado res/layout/activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<ScrollView
android:id="@+id/view_scroll"
android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<ViewFlipper
android:id="@+id/view_flipper"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_margin="6dip" >

<!-- Definimos los hijos que contendrán nuestro viewFlipper -->

<!-- Layout 1 para nuestro slide -->
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:orientation="vertical" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:text="Slide 1"
android:textColor="#191975"
android:textSize="25dp"
android:textStyle="bold" >
</TextView>

<ImageView
android:layout_marginTop="15dp"
android:id="@+id/imageView1"
android:layout_width="450dp"
android:layout_height="450dp"
android:src="@drawable/image1" />

</LinearLayout>

<!-- Layout 2 de nuestro slide -->
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:orientation="vertical" >

<TextView
android:layout_marginTop="15dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Slide 2"
android:textColor="#191975"
android:textSize="25dp"
android:textStyle="bold" >
</TextView>

<ImageView
android:layout_marginTop="15dp"
android:id="@+id/imageView2"
android:layout_width="450dp"
android:layout_height="450dp"
android:src="@drawable/image2" />

</LinearLayout>

<!-- Layout 3 de nuestro slide -->

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:orientation="vertical" >

<TextView
android:layout_marginTop="15dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Slide 3"
android:textColor="#191975"
android:textSize="25dp"
android:textStyle="bold" >
</TextView>

<ImageView
android:layout_marginTop="15dp"
android:id="@+id/imageView3"
android:layout_width="450dp"
android:layout_height="450dp"
android:src="@drawable/image3" />

</LinearLayout>


</ViewFlipper>

<!-- Aquí podéis añadir más elementos -->

</LinearLayout>

</ScrollView>

</LinearLayout>

Una vez tengamos esto realizado, deberemos dirigirnos a nuestra clase que controlará dicha actividad. Que en mi caso es:

MainActivity.java

package "VUESTRO PAQUETE";

import android.content.Context;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.ViewFlipper;

public class MainActivity extends ActionBarActivity implements View.OnClickListener {

// Definimos las variables de nuestro slide
private static final int SWIPE_MIN_DISTANCE = 120;
private static final int SWIPE_MAX_OFF_PATH = 250;
private static final int SWIPE_THRESHOLD_VELOCITY = 200;
private GestureDetector gestureViewFlipperDetector = null;
View.OnTouchListener gestureViewFlipperListener = null;
private ViewFlipper viewFlipper = null;
private GestureDetector gestureScrollViewDetector = null;
View.OnTouchListener gestureScrollViewListener = null;
private ScrollView scrollView = null;

override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

// Instanciamos la clase que detecta el touch del dedo. Y se lo asignamos al ViewFlipper.
gestureViewFlipperDetector = new GestureDetector(new GestureDetectorViewFlipper());
gestureViewFlipperListener = new View.OnTouchListener() {
override
public boolean onTouch(View v, MotionEvent event) {
return gestureViewFlipperDetector.onTouchEvent(event);
}
};
viewFlipper = (ViewFlipper) findViewById(R.id.view_flipper);
viewFlipper.setOnTouchListener(gestureViewFlipperL istener);

// Aquí fallaba yo, que hay que duplicar dicho código para el elemento de ScrollView.
gestureScrollViewDetector = new GestureDetector(new GestureDetectorScrollView());
gestureScrollViewListener = new View.OnTouchListener() {
override
public boolean onTouch(View v, MotionEvent event) {
return gestureScrollViewDetector.onTouchEvent(event);
}
};
scrollView = (ScrollView) findViewById(R.id.view_scroll);
scrollView.setOnTouchListener(gestureScrollViewLis tener);

}

// Clase que dectecta el movimiento en el ViewFlipper
class GestureDetectorViewFlipper extends GestureDetector.SimpleOnGestureListener {
override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
try {
if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
return false;
slide(e1, e2, velocityX, velocityY, viewFlipper);
} catch (Exception e) {
// nothing
}
return false;
}
}

// Clase que dectecta el movimiento del scroll. Exactamente igual que para el viewFlipper
class GestureDetectorScrollView extends GestureDetector.SimpleOnGestureListener {
override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
try {
if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
return false;
slide(e1, e2, velocityX, velocityY, viewFlipper);
} catch (Exception e) {
// nothing
}
return false;
}
}

// Este método es el responsable de realizar la animación cuando se captura el movimiento del dedo
public void slide(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY, ViewFlipper vfpr){
if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY)
moverDerecha(MainActivity.this, vfpr);
else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY)
moverIzquierda(MainActivity.this, vfpr);
}

// Mover a la siguiente imágen del slide
public void moverDerecha(Context c, ViewFlipper vfp){
vfp.setInAnimation(c, R.anim.in_from_right);
vfp.setOutAnimation(c, R.anim.out_to_left);
vfp.showNext();
}

// Mover a la anterior imágen del slide
public void moverIzquierda(Context c, ViewFlipper vfp){
vfp.setInAnimation(c, R.anim.in_from_left);
vfp.setOutAnimation(c, R.anim.out_to_right);
vfp.showPrevious();
}

override
public void onClick(View v) {

}
}

os dejo también un .zip el cual son los estilo de izquierda y derecha, está carpeta la tendréis que descomprimir en vuestro proyecto /res/anim/, si no la tienes creala.

Espero que os sirva y si me equivocado en algo contarme. Y correguimos o si conocéis alguna forma más rápida y mejor. Un saludo.

androizado
05/03/15, 12:30:08
Tras largos minutos y horas de investigación lo logre solucionar, intentaré hacer un repositorio por si le puede servir a alguien :)

Un saludo a todos.

Dexafree
06/03/15, 19:56:52
Siempre es buena práctica compartir el código con la solución, si finalmente haces el repo no dudes en publicarlo aqui :ok:

Marcamos como solucionado!