ViewPager setCurrentItem(pageId,true)不平滑滚动

我正在编译SDK 4.03,三星注入Android 2.2,支持Android库4,并在我的应用程序中使用ViewPager,实际刷卡工作正常,但是当我做

viewPager.setCurrentItem(id); // , or viewPager.setCurrentItem(id, true); 

它不平滑滚动,但立即切换视图。 尽pipe文档中明确指出这是将第二个参数设置为true的目的。 这是怎么回事?

我通过创build一个使用reflection来覆盖ViewPager.mScroller的MyViewPager来解决这个问题。

 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*/); } } } 

这就是我所做的。 我通过将自己的自定义子类放在同一个包中,覆盖了smoothScrollTo中的包私有方法smoothScrollTo 。 它被传递一个零值,这导致了捕捉行为,而不是平滑滚动。

 package android.support.v4.view; import android.content.Context; import android.util.AttributeSet; public class MyViewPager extends ViewPager { public MyViewPager(Context context) { super(context); } public MyViewPager(Context context, AttributeSet attr) { super(context, attr); } void smoothScrollTo(int x, int y, int velocity) { super.smoothScrollTo(x, y, 1); } } 

它工作得很好,如果你想要你可以计算和提供实际的速度ISO只有1。

我在一个处理程序中调用了setCurrentItem函数,它对我来说工作的很好。

 new Handler().post(new Runnable() { @Override public void run() { myViewPager.setCurrentItem(1, true); } }); 

希望这可以帮助。

我知道这个线程很老,但这是Google的最好成绩之一。 我现在一直在反复讨论如何解决这个问题。 上面的解决scheme都没有帮助我。 不过,我确实find了适合我的解决scheme。

我的设置目前看起来像是一个viewpager内的列表视图。 当你点击其中一个视图时,它会创build一个新页面并滚动到该页面。 这之前很活泼,但好像是因为我在打电话

 mViewPager.setCurrentItem(intIndex, true); 

从我的OnClickEvent。 viewpager由于某种原因不喜欢这个,所以我做了这个function。 它创build一个在UI线程上运行一个可运行的新线程。 这个可运行的是告诉ViewPager滚动到某个项目。

 public static void scrollToIndex(int index) { final int intIndex = index; //We're going to make another thread to separate ourselves from whatever //thread we are in Thread sepThread = new Thread(new Runnable(){ public void run() { //Then, inside that thread, run a runnable on the ui thread. //MyActivity.getContext() is a static function that returns the //context of the activity. It's useful in a pinch. ((Activity)MyActivity.getContext()).runOnUiThread(new Runnable(){ @Override public void run() { if (mSlidingTabLayout != null) { //I'm using a tabstrip with this as well, make sure //the tabstrip is updated, or else it won't scroll //correctly if(mSlidingTabLayout.getTabStripChildCount() <= intIndex) mSlidingTabLayout.updateTabStrip(); //Inside this thread is where you call setCurrentItem mViewPager.setCurrentItem(intIndex, true); } } }); } }); sepThread.start(); } 

我希望我至less能帮助有人解决这个问题。 祝你好运!

编辑:看看我的答案,我敢肯定,你可以运行在UI线程,它应该工作。 尽pipe如此,我还没有testing过。

我有同样的问题,但今天我find了一个简单的解决scheme。 也许它会帮助你。 首先,让我们假设我们有一个填充整个屏幕的ViewPager。 要在页面之间切换,我已经使用选项卡创build了自己的自定义视图,并将其放在ViewPager上。 点击一个选项卡应该平滑地滚动到ViewPager与setCurrentItem(item,true)适当的页面 – 但它会立即滚动,不光滑! 然后我试图在ViewPager +callback中添加一个简单的button(不是自定义的):

 @Override public void onClick(View v) { viewPager.setCurrentItem(item, true); } 

之后,顺利的滚动盯着工作。 所以,解决scheme非常简单:在Button类中,内部的boolean onTouch(…)侦听器返回true,所以它总是消费触摸事件! 然后,当我在内部布尔onTouch(…)侦听器中用“return true”代替“return false”时,平滑滚动开始为我的自定义选项卡视图工作。

我希望我的成功故事可以帮助你。

ViewPager从版本5改为9,其中一些更改可能与您的问题有关:

  • ViewPager中修复用户界面行为的错误(版本5和6)
  • 修复了ViewPager的许多错误(修订版9)

给你的代码应该工作得很好,我最好的猜测是你的支持库不是最新的。 尝试更新库,如果它不是。

对于那些使用Xamarin的人来说(虽然这个方法也适用于Java),但我可以build议使用基于上述答案的下一个方法(Android支持库v7 AppCompat 19.1.0中的ViewPager):

 public void ScrollSmooth(int i) { var jClass = JNIEnv.GetObjectClass(_pager.Handle); var jMethod = JNIEnv.GetMethodID(jClass, "setCurrentItemInternal", "(IZZI)V"); JNIEnv.CallVoidMethod (_pager.Handle, jMethod, new JValue (i), new JValue (true), new JValue (false), new JValue (1)); } 

它依赖于http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.0.1_r1/android/support/v4/view/ViewPager.java的; ViewPager实现

试试这个代码:

 viewPager.postDelayed(new Runnable() { @Override public void run() { viewPager.setCurrentItem(id, true); } }, 100);