2011-04-06 15 views
6

Tengo un ViewFlipper que debería reaccionar a un gesto arrojado, pero no es así.Android ViewFlipper no voltear

Actividad

@Override 
public void onCreate(Bundle savedInstanceState) { 
    ... 
    listView = this.getListView(); 
    detector = new GestureDetector(this, new FlingGestureListener(listView)); 
    ... 
} 

FlingGestureListener

public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 
    int pos = source.pointToPosition(Math.round(e1.getX()), Math.round(e1.getY())); 
    View v = source.getChildAt(pos - source.getFirstVisiblePosition()); 
    System.out.println("fling: x=" + velocityX + " y=" + velocityY); 
    try { 
     IFlingable flingable = (IFlingable) v; 
     if(velocityY > -200 && velocityY < 200) { 
      if(velocityX < 0) 
       flingable.fling(IFlingable.RIGHT_TO_LEFT); 
      else if(velocityX > 0) 
       flingable.fling(IFlingable.LEFT_TO_RIGHT); 
     } 
    } catch(Exception e) {} 
    return false; 
} 

View con ViewFlipper que implementa IFlingable

public void fling(int direction) { 
    System.out.println("flip: " + direction); 
    switch(direction) { 
     case IFlingable.LEFT_TO_RIGHT: 
      System.out.println("piep"); 
      GUIHelper.setAnimationSlideLeftToRight(context, switcher); 
      switcher.showNext(); 
      break; 
     case IFlingable.RIGHT_TO_LEFT: 
      System.out.println("pup"); 
      GUIHelper.setAnimationSlideRightToLeft(context, switcher); 
      switcher.showPrevious(); 
      break; 
    } 
} 

Disposición

<ViewFlipper android:id="@+id/viewSwitcher" 
    android:layout_height="wrap_content" 
    android:layout_width="match_parent" android:layout_weight="1"  
    android:inAnimation="@anim/slide_in_left" 
    android:outAnimation="@anim/slide_out_right"> 
     <LinearLayout android:layout_height="wrap_content" 
      android:layout_width="match_parent" android:orientation="vertical"> 
      ... 
     </LinearLayout> 
     ... 
    </ViewFlipper> 

Entrar

fling: x=2542.3613 y=95.877945 
flip: 0 
piep 

consigo los mensajes de registro correctamente por lo que el shownext() en el ViewFlipper será ejecutado pero no cambia su punto de vista sobre la interfaz gráfica de usuario. ¿Me estoy perdiendo de algo? Tengo otro diseño con un ViewSwitcher en lugar del Flipper y ese funciona.

EDIT:

Aquí están las clases que faltan:

public class GUIHelper { 
... 

public static void setAnimationSlideLeftToRight(Context context, ViewAnimator switcher) { 
    Animation in = AnimationUtils.loadAnimation(context, R.anim.slide_in_left); 
    Animation out = AnimationUtils.loadAnimation(context, R.anim.slide_out_right); 
    switcher.setInAnimation(in); 
    switcher.setOutAnimation(out); 
} 

public static void setAnimationSlideRightToLeft(Context context, ViewAnimator switcher) { 
    Animation in = AnimationUtils.loadAnimation(context, R.anim.slide_in_right); 
    Animation out = AnimationUtils.loadAnimation(context, R.anim.slide_out_left); 
    switcher.setInAnimation(in); 
    switcher.setOutAnimation(out); 
} 

... 
} 

public interface IFlingable { 

    public static final int LEFT_TO_RIGHT = 0; 
    public static final int RIGHT_TO_LEFT = 1; 

    public void fling(int direction, boolean fling); 

} 
+0

He encontrado el error. No guardé un contexto en algún momento de las clases. El código anterior funciona perfecto. – dbrettschneider

+0

de dónde sacaste "IFlingable"? no puede verlo en la API de Android. también, ¿qué tipo de objeto es "fuente"? también, idk de donde vino "GUIHelper". has hecho algunas cosas en segundo plano que hacen que este ejemplo sea un poco difícil de seguir. – moonlightcheese

+0

Los inventé yo mismo. Edité la publicación y las puse. – dbrettschneider

Respuesta

7

Hola este es el código de golpe se ejecuta en vista de lista al igual que su xml He puesto un ListView con LinearLayout padres en ViewFlipper

import android.app.Activity; 
import android.os.Bundle; 

import android.view.GestureDetector; 

import android.view.GestureDetector.SimpleOnGestureListener; 

import android.view.MotionEvent; 

import android.view.View; 
import android.view.animation.Animation; 
import android.view.animation.AnimationUtils; 
import android.widget.AdapterView; 
import android.widget.ArrayAdapter; 
import android.widget.ListView; 
import android.widget.Toast; 
import android.widget.ViewFlipper; 

import android.widget.AdapterView.OnItemClickListener; 


public class MainActivity extends Activity { 

    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 gestureDetector; 
    View.OnTouchListener gestureListener; 
    private Animation slideLeftIn; 
    private Animation slideLeftOut; 
    private Animation slideRightIn; 
    private Animation slideRightOut; 
    private ViewFlipper viewFlipper; 
    private ListView lv; 
    private String[] city = { "Indore", "Bhopal", "Khargone", "Ujjain", 
     "Nasik", "Pune", "Delhi", "Mumbai", "Noida", "Hyderabad", 
     "Banglore", "Ajmer", "Goa", "Jaipur", "Nagpur", "" }; 
    private String[] country = { "India", "Bhutan", "Kuwait", "USA", }; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main_layout); 
     lv = (ListView) findViewById(R.id.List01); 
     ListView lv2 = (ListView) findViewById(R.id.List02); 

     viewFlipper = (ViewFlipper) findViewById(R.id.flipper); 
     slideLeftIn = AnimationUtils.loadAnimation(this, R.anim.slide_left_in); 
     slideLeftOut = AnimationUtils 
       .loadAnimation(this, R.anim.slide_left_out); 
     slideRightIn = AnimationUtils 
       .loadAnimation(this, R.anim.slide_right_in); 
     slideRightOut = AnimationUtils.loadAnimation(this, 
       R.anim.slide_right_out); 

     gestureDetector = new GestureDetector(new MyGestureDetector()); 
     gestureListener = new View.OnTouchListener() { 
      public boolean onTouch(View v, MotionEvent event) { 
       if (gestureDetector.onTouchEvent(event)) { 
        return true; 
       } 
       return false; 
      } 
     }; 
     lv.setAdapter(new ArrayAdapter<String>(this, 
       android.R.layout.simple_list_item_1, city)); 
     lv2.setAdapter(new ArrayAdapter<String>(this, 
       android.R.layout.simple_list_item_1, country)); 
     lv.setOnItemClickListener(new OnItemClickListener() { 
      public void onItemClick(AdapterView arg0, View view, int position, 
        long id) { 
       // user clicked a list item, make it "selected" 
       Toast.makeText(getBaseContext(), "Item Clicked", 
         Toast.LENGTH_SHORT).show(); 
       // selectedAdapter.setSelectedPosition(position); 
      } 
     }); 
     lv2.setOnItemClickListener(new OnItemClickListener() { 
      public void onItemClick(AdapterView arg0, View view, int position, 
        long id) { 
       // user clicked a list item, make it "selected" 
       Toast.makeText(getBaseContext(), "Item List2 Clicked", 
         Toast.LENGTH_SHORT).show(); 
       // selectedAdapter.setSelectedPosition(position); 
      } 
     }); 
    } 

    class MyGestureDetector extends 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; 
       // right to left swipe 
       if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE 
         && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { 
        viewFlipper.setInAnimation(slideLeftIn); 
        viewFlipper.setOutAnimation(slideLeftOut); 
        viewFlipper.showNext(); 
       } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE 
         && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { 
        viewFlipper.setInAnimation(slideRightIn); 
        viewFlipper.setOutAnimation(slideRightOut); 
        viewFlipper.showPrevious(); 
       } 
      } catch (Exception e) { 
       // nothing 
      } 
      return false; 
     } 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     if (gestureDetector.onTouchEvent(event)) 
      return true; 
     else 
      return false; 
    } 
} 

Incluido el diseño (main_layout) que se utiliza .....

<?xml version="1.0" encoding="UTF-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/linearLayout1" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical" > 

    <LinearLayout 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" > 

     <Button 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="Do not Click Just swipe on remaining area" /> 
    </LinearLayout> 

    <ViewFlipper 
     xmlns:android="http://schemas.android.com/apk/res/android" 
     android:id="@+id/flipper" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" > 

     <LinearLayout 
      android:id="@+id/ViewFlipper01" 
      android:layout_width="fill_parent" 
      android:layout_height="fill_parent" 
      android:orientation="vertical" > 

      <ListView 
       android:id="@+id/List01" 
       android:layout_width="fill_parent" 
       android:layout_height="wrap_content" > 
      </ListView> 
     </LinearLayout> 
+0

He implementado su código para mi ViewFlipper con vista de lista, pero el gesto no funciona para mí :( –

+0

Es el gesto de arrojar y Tocar no son reconocidos en el código que usted ha creado .. –

+0

Si pongo un poco de vista en lugar de ListView, funciona bien. Pero al poner un ListView o ScrollView, ViewFlipper no está volteando. –

0

Este es mi código xml utilizado.

<ViewFlipper 
    android:id="@+id/vf" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    > 
    <LinearLayout 
     android:layout_width="fill_parent" 
     android:layout_height="match_parent" 
     android:orientation="vertical" 
     > 

    <ListView 
     android:id="@+id/list1" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     ></ListView> 
    </LinearLayout> 
    <LinearLayout 
     android:layout_width="fill_parent" 
     android:layout_height="match_parent" 
     android:orientation="vertical" 
     > 
    <ListView 
     android:id="@+id/list2" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     ></ListView> 
    </LinearLayout> 
</ViewFlipper> 

Anulación dispatchTouchEvent en lugar de onTouchEvent

@Override 
    public boolean dispatchTouchEvent(MotionEvent event) { 
     super.dispatchTouchEvent(event); 
     return gestureDetector.onTouchEvent(event); 
    } 

Esto funciona bien :) Scroll View y Flipper tanto funciona bien.

+0

El diseño parece ser f9. ¿Podría compartir su código completo y explicar su requisito exacto? –

+0

@Arpit Garg El código es el mismo que usted había respondido a dbrettschneider. –

+0

He editado el diseño ... pruébalo usando eso ahora –