2016-05-04 1 views
3

Я довольно новичок в программировании на Android, так что это [надеюсь, наверное] глупый вопрос.Пропуск фрагментов во время опрокидывания с помощью FragmentPagerAdapter

Я копирую поведение приложения iOS, у которого есть 4 вкладки внизу.

Первоначально активными являются только 2, первые и последние. Центр 2 активируется только после успешного поиска.

Мне нравится поведение Shift-to-change Android (я могу добавить его в приложение iOS).

Однако я не уверен в правильном способе пропустить два неактивных центра, так что проведите по экрану справа налево от первой вкладки до последней (и наоборот).

Я не вижу никаких крючков в опубликованном API. Думаю, я могу возиться с возвращаемым элементом в getItem() (вместо отправки одного из средних, я иду прямо к последнему), но мне интересно, правильно ли это сделать. Я заинтересован, потому что вы создаете экземпляр экземпляра на getItem(), поэтому это означает, что это не лучшее место для этого.

Любые отзывы об этом? Я знаю, что с Android часто бывает дюжина способов сделать что-то, но обычно это один или два «правильных» способа.

Я хотел бы сделать это правильно.

+0

Я предполагаю, что мне нужно сделать, это переопределить любой код, используемый для выбора входа «позиция». Я не знаю, где это делается. Я буду искать его. –

+0

Думаю, я знаю, где мне нужно идти сюда. Мне нужно переопределить ViewPager своим классом. В настоящее время я создаю экземпляр класса по умолчанию. –

+0

[Этот критерий] (https://guides.codepath.com/android/ViewPager-with-FragmentPagerAdapter), похоже, имеет то, что мне нужно. Когда я закончу, я отвечу на вопрос о потомстве. –

ответ

0

OK. Я сказал, что сообщаю, как я «решил» проблему. Он не идеален на 100%, но он работает, и я думаю, что он в основном делает правильные вещи.

Прежде всего, я использовал the TabLayout system, где вы создаете объект TabLayout и даете ему ViewPager и FragmentPagerAdapter.

Я узнал, что окончательный номер Tab class. Вы не можете подклассифицировать его. Это означало, что мне нужно было использовать Фрагменты для состояния (включено/отключено). Вы можете включить или отключить интерактивную вкладку, но я добавил флаг «enabled» в подкласс Fragment. Это то, что я использую для запроса состояния вкладки.

Затем я создал встроенный класс в подклассе адаптера. Я реализовал ViewPager.OnPageChangeListener (Это интерфейс):

private class MyTabPagerListener implements ViewPager.OnPageChangeListener 

добавить, что в TabLayout в качестве слушателя:

mViewPager.addOnPageChangeListener(new MyTabPagerListener(mTabLayout,this)); 

Тогда я реализовал "пропуском" код в методе onPageSelected(). Я пытаюсь предвидеть, где идет выбор, поэтому я могу перейти к соответствующей вкладке. Вся идея состоит в том, чтобы выяснить направление. Если следующая выбранная вкладка отключена, то продолжайте:

public void onPageSelected(int position) { 
    AWrapperBaseFragment fragment = (AWrapperBaseFragment)mAdapter.getItem(position); 
    mSkipToPosition = -1; // This will inform the "wrap up" function that we need to skip to another tab. 

    if (!fragment.isEnabled()) { 
     Log.d(TAG, "Page " + position + " is disabled, selecting a different one."); 
     int oldPosition = mTabLayout.getSelectedTabPosition(); 
     if (position > oldPosition) { 
      Log.d(TAG, "Going up."); 
      for (int i = position + 1; i < mAdapter.getCount(); i++) { 
       AWrapperBaseFragment comp_fragment = (AWrapperBaseFragment)mAdapter.getItem(i); 
       if (comp_fragment.isEnabled()) { 
        mSkipToPosition = i; 
        break; 
       } 
      } 
     } 

     if (mSkipToPosition == -1) { 
      Log.d(TAG, "Going down."); 
      for (int i = position - 1; i > -1; i--) { 
       AWrapperBaseFragment comp_fragment = (AWrapperBaseFragment)mAdapter.getItem(i); 
       if (comp_fragment.isEnabled()) { 
        mSkipToPosition = i; 
        break; 
       } 
      } 
     } 
    } 

    mSelectedPosition = position; 

    if (mSkipToPosition == -1) { 
     mSkipToPosition = mSelectedPosition; 
    } 

    Log.d(TAG, "Page selection will " + ((mSelectedPosition != mSkipToPosition) ? ("change from " + mSelectedPosition + " to " + mSkipToPosition) : "not be changed.")); 
} 

Эта функция устанавливает семафор, который осуществляется в функции обратного вызова изменения состояния:

public void onPageScrollStateChanged(int state) { 
    Log.d(TAG, "New Scroll State for page " + mSelectedPosition + ": " + state); 
    if ((state == 0) && (mSkipToPosition > -1) && (mSkipToPosition != mSelectedPosition)) { 
     Log.d(TAG, "This is a disabled page, so page selection will change from " + mSelectedPosition + " to " + mSkipToPosition + "."); 
     mViewPager.setCurrentItem(mSkipToPosition, true); 
    } 
} 

Как я сказал, это не идеально. Там заметная нерешительность, и вы по-прежнему видите содержимое вкладки отключено (так что не оставляйте slop в заблокированных вкладках).

Это намного сложнее, чем решение iOS, но я думаю, что это сработает. Я еще не закончил тестирование.

Смежные вопросы