2012-08-17 14 views
9

Estoy escribiendo una aplicación que usa ViewPager para alojar Fragment s.El desplazamiento suave no funciona en ViewPager (biblioteca de soporte)

Cuando cambio el fragmento mediante programación la función de desplazamiento suave no funciona. Yo uso el método ViewPager.setCurrentItem (int item, boolean smoothScroll) `.

Quizás alguien sepa una solución a este error? Tal vez con animaciones?

EDIT: Estoy usando el paquete de ayuda. Y el problema es que si uso ViewPager.setCurrentItem(2, true) o ViewPager.setCurrentItem(2, false) el resultado es el mismo. La vista cambia muy rápido (no suavemente).

+0

En primer lugar, el viewpager SÓLO existe en el paquete de soporte. Ahora la pregunta sería, ¿cuál es el problema que enfrenta? si establece setCurrentItem (2, false) ¿qué hace en su lugar? ¿Puedes editar tu pregunta para que sea un poco más específica? –

+0

Así que puse mPager.setCurrentItem (1, verdadero); en un postrunnable para dar una pista al usuario de que el objeto es un viewpager. El problema es que no hay animación cuando lo pongo en el postrunnable que mata el punto. ¿Hay alguna otra manera de que yo pueda hacer esto? – MinceMan

Respuesta

-1

Lo que funcionó para mí fue llamar a mPager.setCurrentItem después del mPagerAdapter.notifyDataSetChanged(), y no como un ejecutable publicado.

Aquí es un ejemplo (en MonoDroid):

public void UpdateDetialsView(string type) 
    { 
     string typeName4 = Java.Lang.Class.FromType(typeof(ParcelRecordComplaintDetailsView)).Name; 

     if (_fragments.Count > 3) 
     { 
      _fragments.RemoveAt(_fragments.Count - 1); 

      //////////////////////////////////////////////////////////// 
      // Called here it wasn't working for me (Posted or not) 

      //_viewPager.Post(new Action(() => { _viewPager.SetCurrentItem(3, true); })); 
     } 

     _fragments.Add(Fragment.Instantiate(Activity, typeName4)); 

     _pagerAdapter.NotifyDataSetChanged(); 

     //////////////////////////////////////////////////////////// 
     // Called here it works as expected 

     _viewPager.SetCurrentItem(3, true); 
    } 

donde

protected MyAdapter _pagerAdapter; 
    protected ViewPager _viewPager; 
    private List<Android.App.Fragment> _fragments; 

y

public class MyAdapter : Android.Support.V13.App.FragmentStatePagerAdapter 
    { 
     private List<Fragment> _fragments; 

     public override Java.Lang.Object InstantiateItem(View p0, int p1) 
     { 
      return base.InstantiateItem(p0, p1); 
     } 

     public MyAdapter(Android.App.FragmentManager fm) : base(fm) 
     { 

     } 

     public MyAdapter(Android.App.FragmentManager fm, List<Android.App.Fragment> fragments) : base(fm) 
     { 
      _fragments = fragments; 
     } 

     public override int Count 
     { 
      //get { return FRAG_PAGES; } 
      get { return _fragments.Count; } 
     } 

     public override Android.App.Fragment GetItem(int p0) 
     { 
      return _fragments[p0]; 
     } 

     public override float GetPageWidth(int p0) 
     { 
      //return base.GetPageWidth(p0); 

      return (float) (0.5f); 
     } 

     public override int GetItemPosition(Java.Lang.Object p0) 
     { 
      //return base.GetItemPosition(p0); 
      return PagerAdapter.PositionNone; 
     } 
    } 
+0

Interesante. Estás cambiando los fragmentos, ¿es correcto? No cambio los fragmentos ellos mismos solo tratando de cambiar entre ellos. Intentaré algo con esta idea NotifyDataSetChanged(). ¡Gracias! – Tautvydas

+0

Sí, los estoy cambiando dinámicamente. Tengo 4 paneles de media pantalla que se implementan como fragmentos y se alojan dentro de un ViewPager. Cada panel muestra los detalles de un elemento del panel a su izquierda (y es por eso que los estoy actualizando dinámicamente). No creo que NotifyDataSetChanged hiera nada si lo llamas sin haber cambiado nada de antemano, aunque no estoy seguro si será de ayuda (si no lo hace, tal vez puedas cambiar algo en un fragmento muy pequeño, cámbialo Atrás, luego llame a NotifyDataSetChanged, para forzarlo?). – samosaris

17

He arreglado esto creando una MyViewPager que anula la ViewPager. mScroller usando la reflexión.

public class MyViewPager extends ViewPager 
{ 
    public MyViewPager(Context context, AttributeSet attrs) 
    { 
    super(context, attrs); 
    setMyScroller(); 
    } 
    private void setMyScroller() 
    { 
    try 
    { 
      Class<?> viewpager = ViewPager.class; 
      Field scroller = viewpager.getDeclaredField("mScroller"); 
      scroller.setAccessible(true); 
      scroller.set(this, new MyScroller(getContext())); 
    } catch (Exception e) 
    { 
     e.printStackTrace(); 
    } 
    } 

    public class MyScroller extends Scroller 
    { 
    public MyScroller(Context context) 
    { 
     super(context, new DecelerateInterpolator()); 
    } 

    @Override 
    public void startScroll(int startX, int startY, int dx, int dy, int duration) 
    { 
     super.startScroll(startX, startY, dx, dy, 1000 /*1 secs*/); 
    } 
    } 
} 
+0

Esta solución es desagradable, pero debería funcionar. Gracias, intentaré implementar tu sugerencia. – Tautvydas

+0

Acepto que es una solución para un error de ViewPager (IMO) –

+5

Si usa esta solución provisional y ProGuard, debe agregar esto a su configuración de ProGuard: '-clave claseclase clase android.support.v4.view. ViewPager { \t private android.widget.Scroller mScroller; } ' – Iftah

Cuestiones relacionadas