10

Estoy tratando de agregar alguna indicación visual, que no hay más páginas en la dirección deseada de fling en ViewPager. Sin embargo, estoy luchando por encontrar un lugar, donde poner el código relevante.indicación visual de sobre desplazamiento en android

He intentado extender la clase ViewPager con el siguiente código, pero el Toast no se muestra (ev.getOrientation() devuelve siempre 0). También he intentado lo mismo con los puntos del historial, pero ev.getHistorySize() también devuelve 0.

¿Qué me estoy perdiendo?

ejemplo Clase:

public class CustomViewPager extends ViewPager { 

    public CustomViewPager(Context context) { 
     super(context); 
    } 

    public CustomViewPager(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    /** 
    * @see android.support.v4.view.ViewPager#onTouchEvent(android.view.MotionEvent) 
    */ 
    @Override 
    public boolean onTouchEvent(MotionEvent ev) { 
     boolean result = super.onTouchEvent(ev); 

     switch (ev.getAction() & MotionEventCompat.ACTION_MASK) { 
      case MotionEvent.ACTION_MOVE: 
       if (ev.getOrientation() > 0) { 
        Toast.makeText(getContext(), "left", 0).show(); 
       } 
     } 

     return result; 
    } 
} 

Respuesta

-1

lo general, con ViewPager, uno utiliza un PagerAdapter como FragmentPagerAdapterFragmentStatePagerAdapter o para inundar el ViewPager con contenidos (su contenido va a ser vistas).

Ahora, cuando utiliza un PagerAdapter, tiene un método llamado getCount(), http://developer.android.com/reference/android/support/v4/view/PagerAdapter.html#getCount%28%29, que le dará el tamaño del contenido.

Como ahora conoce el tamaño, puede visualizar fácilmente un mensaje con una instrucción de control if.

probar este código: http://developer.android.com/reference/android/support/v4/view/ViewPager.html

Nota: No creo que necesita una costumbre ViewPager. También necesitarás comprender Fragmentos para ViewPager. Mire muestras en ApiDemos. Es una gran fuente.

+0

Eso no era lo preguntó. Quería saber específicamente cómo hacer un efecto de desbordamiento como la goma elástica en iOS, que falta en ViewPager al menos hasta ICS. –

1

Tiene muchas opciones, puede mostrar un Toast, mostrar un cuadro de diálogo, hacer que TextView o una imagen aparezca sobre su UI, etc. O porque sabe la cantidad de elementos Ver en ViewPager, puede agregar diferente Ver en las posiciones 0 y/o n + 1 con el mensaje y hacerlo rebotar a la última Vista que realmente contiene sus datos.

Se podría implementar:

viewPager.setOnPageChangeListener(new OnPageChangeListener() { 
    public void onPageSelected(int position) { 
     //TODO If position is the 0 or n item, add a view at 0 or at n+1 to indicate there is no more pages with data. 
    } 

    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 
     // TODO Show a Toast, View or do anything you want when position = your first/last item; 
    } 

    public void onPageScrollStateChanged(int state) { 
    } 
}); 
+2

Hay un efecto de brillo estándar del sistema cuando intenta desplazarse más allá del final de un ViewPager, que es el mismo que cuando se desplaza más allá de la parte superior de la parte inferior de una lista. Me gustaría algo así, pero debería funcionar en todas las versiones (el brillo actual es solo ICS). Sus sugerencias podrían dar lugar a una interfaz de usuario torpe, y si esas son realmente las únicas opciones, entonces me quedaré sin indicación. –

+0

Lo sé y es suficiente para mi aplicación, pero si @ekramus me pregunta, supongo que es porque necesita algo más. :) –

0

Usted puede sobrecargar la función setUserVisibleHint (booleano) en sus fragmentos. pseudo código:

void setUserVisibleHint(boolean isVisibleToUser) { 
     // If this fragment is becoming visible 
     if (isVisibleToUser == true) { 
      // Check if it is the last fragment in the viewpager 
      if (indexOfThis == getActivity().indexOfLast) { 
       // Display right limit reached 
       Toast(..., "No more Frags to right",...) 
       } 
      // Check if it is the first fragment in the viewpager 
      else if (indexOfThis == getActivity().indexOfFirst) { 
       // Display Left Limit reached 
       Toast(..., "No more Frags to left",...) 
      } 
     } 
    } 

no he utilizado esta función para este propósito, pero lo han utilizado por otras razones y lo hace el fuego de manera apropiada. Espero que esto ayude ...

+0

Esto tiene las mismas implicaciones de IU que la respuesta de Oscar, excepto que anula un método que no se debe anular en lugar de usar un oyente, lo que parece peligroso. –

19

Si miras la biblioteca de soporte v4 verás que hay una clase utilizada por ViewPager llamada EdgeEffectCompat (esto proporciona el efecto de brillo cuando llegas al principio o al final de un buscapersonas en ICS +) Si observa la implementación en la biblioteca de compatibilidad, verá que tiene una instrucción if para ver si la versión de compilación es 14+ (ICS) o no. Si es así, finalmente termina (si trazas el tiempo suficiente) usando la clase normal EdgeEffect que se introdujo en ICS. De lo contrario, utiliza BaseEdgeEffectImpl, que básicamente no tiene nada.

Si lo desea, puede crear su propia ViewPager personalizada que use EdgeEffect usted mismo. Puede consultar el código fuente de Android para ver cómo implementaron EdgeEffect here, que puede copiar prácticamente (solo asegúrese de copiar los formularios overscroll_edge y overscroll_glow en los directorios AOSP/res/drawable en su propio proyecto, ya que son internos a Android) o seguir adelante y crear su propia versión.

Buena suerte.

(Por cierto, esa es la forma en que crean el efecto fresco inclinación borde mirando en el menú de inicio en ICS ... así que se puede casi ser tan creativo como usted desea con este;)

+0

¡Parece que debería hacerlo! Gracias. –

7

yo estaba tratando para obtener exactamente el mismo efecto que se hizo en esta pregunta. Lucho con eso y luego leo @wnafee answer (no podría hacerlo sin él).

Pero luego me cuesta implementar lo que es bastante simple por la respuesta. Tuve tantos problemas con su implementación, que quizás no entendía la respuesta correctamente, pero había demasiados problemas con las API inaccesibles, ya que no estaba trabajando en el mismo paquete de la biblioteca de compatibilidad.

Después de probar algunos enfoques (ninguno de ellos tuvo éxito, y fueron bastante complicados) fui en una dirección ligeramente diferente, y ahora funciona como un encanto. Usé un reflejo, para los que nunca lo usaron, no se preocupen, es realmente el básico de la reflexión.

No estoy seguro de si es la mejor solución que existe, pero funcionó para mí, así que si desea utilizarla, puede hacerlo. Por favor, lea el ejemplo de Wnafee ya que explica algunas de las cosas que hice.

Para realizar esta tarea, simplemente debe seguir mi solución de tres partes. (Tendrá que tomar entre 3-10 minutos)

Parte I:

Como Wnafee dijo que acabo de hacer mi propia clase EdgeEffect por copiar y pegar el código fuente de la here,

(solo asegúrese de copiar el overscroll_edge y overscroll_glow dibujables en los directorios/res/dibujable AOSP a su propio proyecto ya que son internos al androide)

Sólo hice 2 muy pequeños cambios:

  1. Declaro que la clase extiende EdgeEffectCompat (llamé a mi clase EdgeEffectForEarlyVersions). public class EdgeEffectForEarlyVersions extends EdgeEffectCompat. La razón para hacer este cambio es que mLeftEdge y mRightEdge son del tipo EdgeEffectCompat.
  2. En la primera línea del constructor de "mi" nueva clase, agregué una llamada al constructor padre super(context);. Como no existe un constructor predeterminado para EdgeEffectCompat, debe llamar explícitamente al constructor.

Parte II

Además de eso escribí la otra función. El objetivo de la función es que, en el caso de una versión anterior (antes de ICS), nos gustaría utilizar el EdgeEffectForEarlyVersions que acabamos de copiar. Para lograr ese propósito, usé la reflexión.

Ésta es la función:

private static void changeEdgeEffectCompactOnEarlyVersions(ViewPager viewPager, Context context) 
{ 
    /* In case that the version is earlier than 14 there is only empty implementation for the edge effect, therefore we change it. 
    * for more information look on the following links: 
    * 1. http://stackoverflow.com/questions/10773565/visual-indication-of-over-scroll-in-android 
    * 2. http://grepcode.com/file/repo1.maven.org/maven2/com.google.android/support-v4/r7/android/support/v4/view/ViewPager.java#ViewPager.0mLeftEdge 
    * 3. http://grepcode.com/file/repo1.maven.org/maven2/com.google.android/support-v4/r7/android/support/v4/widget/EdgeEffectCompat.java#EdgeEffectCompat 
    */ 

    if (Build.VERSION.SDK_INT < 14) 
    { 
     try 
     { 
      Class<ViewPager> viewPagerClass = ViewPager.class; 
      //Get the left edge field, since it is private we used getDeclaredField and not getDeclared 
      Field leftEdge = viewPagerClass.getDeclaredField("mLeftEdge"); 
      leftEdge.setAccessible(true); 
      //Get the right edge field, since it is private we used getDeclaredField and not getDeclared 
      Field rightEdge = viewPagerClass.getDeclaredField("mRightEdge"); 
      rightEdge.setAccessible(true); 

      EdgeEffectForEarlyVersions leftEdgeEffect = new EdgeEffectForEarlyVersions(context); 
      EdgeEffectForEarlyVersions rightEdgeEffect = new EdgeEffectForEarlyVersions(context); 

      //Set the mLeftEdge memeber of viewPager not to be the default one, but to be "our" edgeEffect 
      leftEdge.set(viewPager, leftEdgeEffect); 
      //Set the mRightEdge memeber of viewPager not to be the default one, but to be "our" edgeEffect 
      rightEdge.set(viewPager, rightEdgeEffect);    
     } 
     catch (Exception ex) 
     { 
      Log.e("refelection", ex.getMessage()); 
     } 

    } 
} 

Parte III

Ahora todo lo que queda por hacer, es llamar a esa función después de que la instancia se ViewPager y nada más.

Espero que ayude a alguien.

+0

Esto no funcionará en API <= 8. (en la última revisión 11) utilizando v4 compat lib. Porque usa BaseViewCompatImpl que siempre devuelve OVER_SCROLL_NEVER cuando se le solicita el modo de desplazamiento en exceso. En el onDraw(), se salta el dibujo del desplazamiento en exceso ... – Nick

1

solo para complementar @goBeepit dev answer cuando crea su propia clase edgeffect y se extiende desde EdgeEffectCompat, algunos métodos requieren ser booleanos. puede cambiar esos métodos al tipo booleano y hacer luego devolver verdadero en cualquier caso, de esta manera todo funciona bien

Cuestiones relacionadas