Плавная прокрутка не работает в ViewPager (поддержка библиотеки)

Я пишу приложение, которое используетViewPager принимать гостейFragments.

Когда я изменяю фрагмент программно, функция плавной прокрутки не работает. Я использую метод ViewPager.setCurrentItem (int item, boolean smoothScroll).

Может быть, кто-нибудь знает обойти эту ошибку? Может быть, с анимацией?

РЕДАКТИРОВАТЬ: Я использую пакет поддержки. И вопрос в том, использую ли яViewPager.setCurrentItem(2, true) или жеViewPager.setCurrentItem(2, false) результат тот же. Вид переключается очень быстро (не плавно).

 MinceMan25 нояб. 2012 г., 16:56
Поэтому я поставил mPager.setCurrentItem (1, true); в postrunnable дать пользователю подсказку, что объект является пейджером. Проблема в том, что анимация отсутствует, когда я помещаю ее в postrunnable, что убивает точку. Есть ли другой способ, которым я мог бы сделать это?
 Jorge Aguilar22 авг. 2012 г., 21:22
Прежде всего, viewpager ТОЛЬКО существует в пакете поддержки. Теперь возникает вопрос, с какой проблемой вы сталкиваетесь? если вы делаете setCurrentItem (2, false), что он делает вместо этого? Вы можете отредактировать свой вопрос, чтобы быть немного более конкретным?

Ответы на вопрос(2)

Решение Вопроса

создав MyViewPager, который переопределяет ViewPager.mScroller с помощью отражения.

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*/);
    }
  }
} 
 22 мар. 2013 г., 16:01
Я согласен, что это обходной путь для ошибки ViewPager (IMO)
 16 февр. 2014 г., 14:43
Если вы используете этот обходной путь и ProGuard, вам необходимо добавить его в конфигурацию ProGuard:-keepclassmembers class android.support.v4.view.ViewPager { private android.widget.Scroller mScroller; }
 Tautvydas22 мар. 2013 г., 15:27
Это решение неприятно, но на самом деле должно работать! Спасибо, я постараюсь реализовать ваше предложение.

что мне помогло, это вызвать mPager.setCurrentItem после mPagerAdapter.notifyDataSetChanged (), а не как опубликованный исполняемый файл.

Вот пример (в 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);
    }

где

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

а также

    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;
        }
    }
 Tautvydas03 дек. 2012 г., 12:38
Интересно. Вы меняете фрагменты, это правильно? Я не изменяю сами фрагменты, просто пытаюсь переключаться между ними. Я попробую кое-что с этой идеей NotifyDataSetChanged (). Спасибо!
 03 дек. 2012 г., 17:37
Да, я меняю их динамически. У меня есть 4 половины экрана панели, которые реализованы в виде фрагментов и размещены внутри ViewPager. Каждая панель отображает подробности элемента от панели слева (и именно поэтому я их динамически обновляю). Я не думаю, что NotifyDataSetChanged должен повредить что-либо, если вы вызываете его, фактически не изменив ничего заранее, хотя я не уверен, поможет ли это (если это не так, возможно, вы можете что-то изменить в очень незначительном фрагменте, измените его назад, затем вызвать NotifyDataSetChanged, чтобы заставить его?).

Ваш ответ на вопрос