Как я могу получить текущий фрагмент из ViewPager? [Дубликат]

Здесь я попытался с помощью этого подхода:

import numpy as np
#converting to one_hot





def one_hot_encoder(value, datal):

    datal[value] = 1

    return datal


def _one_hot_values(labels_data):
    encoded = [0] * len(labels_data)

    for j, i in enumerate(labels_data):
        max_value = [0] * (np.max(labels_data) + 1)

        encoded[j] = one_hot_encoder(i, max_value)

    return np.array(encoded)
169
задан rick 4 September 2013 в 10:25
поделиться

28 ответов

, выбрав опцию, мне нужно обновить фрагмент, который в настоящее время виден.

Простым способом сделать это является использование трюка, связанного с реализацией FragmentPagerAdapter :

case R.id.addText:
     Fragment page = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":" + ViewPager.getCurrentItem());
     // based on the current position you can then cast the page to the correct 
     // class and call the method:
     if (ViewPager.getCurrentItem() == 0 && page != null) {
          ((FragmentClass1)page).updateList("new item");     
     } 
return true;

Пожалуйста, переосмыслите свое соглашение об именах переменных, используя в качестве имени переменной имя класса очень сбивает с толку (поэтому нет ViewPager ViewPager, например, используйте ViewPager mPager).

157
ответ дан Luksprog 19 August 2018 в 15:09
поделиться
  • 1
    Является ли этот фрагмент надежным, если API изменяется? – Maarten 29 January 2014 в 00:18
  • 2
    @Maarten Нет, это обычный хак, который использовался с момента появления адаптера (и его исходный код был доступен), он еще не изменился. Если вы хотите что-то более надежное, вам нужно будет использовать другие параметры, наиболее заметные, переопределяя метод instantiateItem() и сами ссылаясь на соответствующие фрагменты. – Luksprog 29 January 2014 в 08:48
  • 3
    После нескольких часов разочарования и запроса страниц непосредственно из mAdapter.getItem(position), удивительного ... По крайней мере сейчас я знаю, что другие 8512 испытаний не сработали. благодаря – Diolor 7 April 2014 в 21:24
  • 4
    Обратите внимание, что это не работает, если вы используете FragmentStatePagerAdapter, а не FragmentPagerAdapter. – Shawn Lauzon 29 June 2015 в 19:40
  • 5
    Позор в команде Google Android для создания такого дерьма. – Oliver Dixon 4 February 2016 в 09:32
final ViewPager.OnPageChangeListener onPageChangeListener =
    new ViewPager.OnPageChangeListener() {
      @Override public void onPageSelected(int position) {
        switch (position) {
          case 0:
            FragmentClass1 frag1 =
                (FragmentClass1) viewPager.getAdapter()
                    .instantiateItem(viewPager, viewPager.getCurrentItem());
            frag1.updateList("Custom text");
            break;
          case 1:
            break;
          case 2:
            break;
        }
      }

      @Override
      public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

      }

      @Override public void onPageScrollStateChanged(int state) {
      }
    };


 viewPager.addOnPageChangeListener(onPageChangeListener);

viewPager.setAdapter(adapter);


viewPager.post(new Runnable() {
  @Override public void run() {
    onPageChangeListener.onPageSelected(viewPager.getCurrentItem());
  }
});

Иногда фрагмент может отправлять нулевой объект, поэтому вы можете запустить новый Runnable для решения проблемы при первой загрузке.

Спасибо, rick

0
ответ дан Benjamín Rengifo 19 August 2018 в 15:09
поделиться
  • 1
    Пожалуйста, добавьте текст, объясняющий, почему этот код решит проблему OP. Кроме того, учитывая, сколько еще ответов есть, объясните, почему этот ответ лучше, чем те, которые уже даны. Помогите другим понять. – APC 4 December 2015 в 06:46
  • 2
    OnPageChangeListener устарел. – Oliver Dixon 4 February 2016 в 09:38

У меня была такая же проблема и я решил использовать этот код.

MyFragment fragment = (MyFragment) thisActivity.getFragmentManager().findFragmentById(R.id.container);

Просто замените имя MyFragment на имя вашего фрагмента и добавьте идентификатор вашего контейнера фрагментов.

1
ответ дан Bilal Soomro 19 August 2018 в 15:09
поделиться

Я использовал следующее:

 int index = vpPager.getCurrentItem();
 MyPagerAdapter adapter = ((MyPagerAdapter)vpPager.getAdapter());
 MyFragment suraVersesFragment = (MyFragment)adapter.getRegisteredFragment(index);
3
ответ дан BlaShadow 19 August 2018 в 15:09
поделиться
  • 1
    Это работает для меня и намного проще, чем кажется, чем принятый ответ – real 19 7 February 2015 в 08:42
  • 2
    Это зависит от пользовательской реализации пейджера из найденного здесь ответа: stackoverflow.com/questions/8785221/… – Tom Redman 24 February 2015 в 00:29
  • 3
    Это именно то, что я пытался сделать, но не зная, какие методы переопределить, потратил бы впустую часы - спасибо! – Bron Davies 22 January 2016 в 07:34

Получить текущий фрагмент - получить позицию в ViewPager в public void onPageSelected (конечная позиция int), а затем

public PlaceholderFragment getFragmentByPosition(Integer pos){
    for(Fragment f:getChildFragmentManager().getFragments()){
        if(f.getId()==R.viewpager && f.getArguments().getInt("SECTNUM") - 1 == pos) {
            return (PlaceholderFragment) f;
        }
    }
    return null;
}

SECTNUM - аргумент позиции, назначенный публичному статическому PlaceholderFragment newInstance (int sectionNumber); of fragment

getChildFragmentManager () или getFragmentManager () - зависит от того, как созданные SectionsPagerAdapter

0
ответ дан Evgeny 19 August 2018 в 15:09
поделиться

Заменить setPrimaryItem из вашего FragmentPagerAdapter: объект является видимым фрагментом:

 @Override
        public void setPrimaryItem(ViewGroup container, int position, Object object) {
            if (mCurrentFragment != object) {
                mCurrentFragment = (LeggiCapitoloFragment) object;
            }
            super.setPrimaryItem(container, position, object);
        }
0
ответ дан Flavio Barisi 19 August 2018 в 15:09
поделиться
getSupportFragmentManager().getFragments().get(viewPager.getCurrentItem());

Передайте экземпляр, полученный из указанной выше строки, фрагменту, с которым вы хотите работать. Работает отлично.

viewPager

- это экземпляр пейджера, управляющий фрагментами.

0
ответ дан Gaurav Pangam 19 August 2018 в 15:09
поделиться
  • 1
    Это работает только в том случае, если все страницы загружаются как фрагмент. Когда есть, например, tablayout со многими вкладками / страницами, то не все они загружаются, поэтому это может вызвать исключение indexoutofbounce. – progNewbie 15 August 2018 в 14:29
  • 2
    @progNewbie да, что потребует дополнительного обходного кода. – Gaurav Pangam 17 August 2018 в 06:47
  • 3
    Ответ @progNewbie Evgeny ниже будет обрабатывать эту ситуацию, я думаю – Gaurav Pangam 17 August 2018 в 06:49

Текущий фрагмент:

Это работает, если вы создали проект с шаблоном табуляции фрагментов.

Fragment f = mSectionsPagerAdapter.getItem(mViewPager.getCurrentItem());

Обратите внимание, что это работает с реализацией шаблона действия с вкладками по умолчанию.

4
ответ дан hasan 19 August 2018 в 15:09
поделиться
  • 1
    Это зависит от вашей реализации getItem () - он может возвращать новый экземпляр фрагмента, который, вероятно, не тот, который вы хотите. – Tom 18 February 2016 в 01:36
  • 2
    Вот как это делается. если вы все еще имеете конфигурацию по умолчанию при создании проекта tabor с фрагментами. никто не имел этого решения. поэтому я подумал, что это поможет. – hasan 18 February 2016 в 20:51

В моей деятельности у меня есть:

int currentPage = 0;//start at the first tab
private SparseArray<Fragment> fragments;//list off fragments
viewPager.setOnPageChangeListener(new OnPageChangeListener() {

@Override
public void onPageSelected(int pos) {
        currentPage = pos;//update current page
}

@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {}
@Override
public void onPageScrollStateChanged(int arg0) {}
});



@Override
public void onAttachFragment(Fragment fragment) {
    super.onAttachFragment(fragment);
    if(fragment instanceof Fragment1)
        fragments.put(0, fragment);
    if(fragment instanceof Fragment2)
        fragments.put(2, fragment);
    if(fragment instanceof Fragment3)
        fragments.put(3, fragment);
    if(fragment instanceof Fragment4)
        fragments.put(4, fragment);
}

Then I have the following method for getting the current fragment

public Fragment getCurrentFragment() {
    return fragments.get(currentPage);
}
0
ответ дан J. Musyoka 19 August 2018 в 15:09
поделиться

FragmentStatePagerAdapter имеет открытый метод с именем instantiateItem, который возвращает ваш фрейм-график на основе заданных значений параметров, этот метод имеет два параметра ViewGroup (ViewPager) и позицию.

public Object instantiateItem(ViewGroup container, int position);

Используется этот метод для получения указанной позиции фрагмент,

Fragment fragment = (Fragment) adaper.instantiateItem(mViewPager, position);

Этот код поможет мне, проверьте его.

20
ответ дан Krunal Shah 19 August 2018 в 15:09
поделиться
  • 1
    Спасибо! Это лучший ответ для FragmentStatePagerAdapter! – Dmitry Velychko 1 April 2018 в 21:30

Здесь много ответов, которые на самом деле не затрагивают основополагающего факта, что НАСТОЯТЕЛЬНО НЕ ИМЕЕТ этого сделать предсказуемо, и таким образом, чтобы вы не стреляли в ногу в какой-то момент в будущем .

FragmentStatePagerAdapter - единственный класс, который знает, как надежно получить доступ к фрагментам, которые отслеживаются с помощью FragmentManager - любая попытка попытаться угадать идентификатор или тег фрагмента не является надежным, долгосрочным , И попытки отслеживания экземпляров вручную, скорее всего, не сработают, когда состояние будет сохранено / восстановлено, потому что FragmentStatePagerAdapter может не вызывать обратные вызовы при восстановлении состояния.

О единственном, что у меня есть был способен заставить работу копировать код для FragmentStatePagerAdapter и добавлять метод, который возвращает фрагмент, с учетом позиции (mFragments.get(pos)). Обратите внимание, что этот метод предполагает, что фрагмент действительно доступен (т. Е. Он был видимым в какой-то момент).

Если вы особенно предприимчивы, вы можете использовать отражение для доступа к элементам частного mFragments списка , но затем мы вернемся к квадрату (имя списка не будет оставаться неизменным).

8
ответ дан Melllvar 19 August 2018 в 15:09
поделиться
  • 1
    для решения проблемы «плохо работать при сохранении / восстановлении состояния», я переопределяю метод saveState (). Так что пейджер не сохраняет какой-либо фрагмент, когда действие приостанавливается. оно работает. – AntoineP 14 August 2015 в 16:41
  • 2
    Это просто добавляет к пэчворку, не устраняя основной проблемы. Я не утверждаю, что это не работает - просто это не очень хорошая реализация. – Melllvar 19 October 2015 в 02:02
    public class MyPagerAdapter extends FragmentPagerAdapter {
        private Fragment mCurrentFragment;

        public Fragment getCurrentFragment() {
            return mCurrentFragment;
        }
//...    
        @Override
        public void setPrimaryItem(ViewGroup container, int position, Object object) {
            if (getCurrentFragment() != object) {
                mCurrentFragment = ((Fragment) object);
            }
            super.setPrimaryItem(container, position, object);
        }
    }
118
ответ дан Mindphaser 19 August 2018 в 15:09
поделиться
  • 1
    Google должен предоставить FragmentPageAdapter.getCurrentPrimaryItem (), возвращающий mCurrentPrimaryItem. – eugene 29 July 2014 в 01:04
  • 2
    Я также использую эту технику. Я также определяю PagerFragment с методами onPageSelected / onPageDeselected и все мои фрагменты пейджера расширяют его. Затем setPrimaryitem может соответствующим образом вызывать эти методы, когда пользователь перебирает новую страницу. Это означает, что вы можете реализовать более ленивую стратегию для загрузки данных на страницах, которые даже не показаны. Однако вы должны иметь в виду, что во время перехода страницы лучше выглядеть, если на следующей странице уже заполнены данные, поэтому ленивая загрузка всех данных в onPageSelected может быть не идеальной. – JHH 18 December 2015 в 10:59
  • 3
    Почему оператор if? Фрагмент просто вызывает метод equals объекта, который является неглубоким сравнением. Так почему бы просто не называть всегда mCurrentFragment = ((Fragment) object);? – Sumido 16 May 2017 в 14:42

Вы можете реализовать BroadcastReceiver во Фрагменте и отправить Intent из любого места. Приемник фрагмента может прослушивать конкретное действие и вызывать метод экземпляра.

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

0
ответ дан nichole 19 August 2018 в 15:09
поделиться

Просто получите текущий элемент из пейджера, а затем попросите адаптер к фрагменту этой позиции.

 int currentItem = viewPager.getCurrentItem();
    Fragment item = mPagerAdapter.getItem(currentItem);
    if (null != item && item.isVisible()) {
       //do whatever want to do with fragment after doing type checking
        return;
    }
1
ответ дан Pankaj kumar 19 August 2018 в 15:09
поделиться

После прочтения всех комментариев и ответов я собираюсь объяснить оптимальное решение этой проблемы. Лучшим вариантом является решение @ rik, поэтому мое улучшение основывается на его.

Вместо того, чтобы задавать каждый FragmentClass, как

if(FragmentClass1){
   ...
if(FragmentClass2){
   ...
}

Создайте свой собственный интерфейс и создайте его дочерние фрагменты, например

public interface MyChildFragment {
    void updateView(int position);
}

Затем вы можете сделать что-то подобное, чтобы инициировать и обновлять внутренние фрагменты.

Fragment childFragment = (Fragment) mViewPagerDetailsAdapter.instantiateItem(mViewPager,mViewPager.getCurrentItem());

if (childFragment != null) {
   ((MyChildFragment) childFragment).updateView();
}

PS Будьте осторожны, когда вы вставляете этот код, если вы вызываете insatiateItem до того, как система действительно создаст его, savedInstanceState вашего дочернего фрагмента будет пустым для него

public void onCreate(@Nullable Bundle savedInstanceState){
      super(savedInstanceState)
}

Сбой вашего приложения.

Удачи

1
ответ дан Pedro Varela 19 August 2018 в 15:09
поделиться

Вы можете определить PagerAdapter как это, тогда вы сможете получить любой Fragment в ViewPager.

private class PagerAdapter extends FragmentPagerAdapter {
    private final List<Fragment> mFragmentList = new ArrayList<>();

    public PagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }

    @Override
    public int getCount() {
        return mFragmentList.size();
    }

    public void addFragment(Fragment fragment) {
        mFragmentList.add(fragment);
    }
}

Чтобы получить текущий Fragment

Fragment currentFragment = mPagerAdapter.getItem(mViewPager.getCurrentItem());
1
ответ дан Phan Van Linh 19 August 2018 в 15:09
поделиться

Я знаю его слишком поздно, но у меня есть очень простые способы сделать это,

// для фрагмента в 0-м случае

((mFragment) viewPager.getAdapter().instantiateItem(viewPager, 0)).yourMethod();
8
ответ дан Pratik Mhatre 19 August 2018 в 15:09
поделиться

, выбрав опцию, мне нужно обновить фрагмент, который в настоящее время виден.

Чтобы получить ссылку на текущий видимый фрагмент, предположим, что у вас есть ссылка на ViewPager как mPager. Затем следующие шаги получат ссылку на currentFragment:

  1. PageAdapter adapter = mPager.getAdapter();
  2. int fragmentIndex = mPager.getCurrentItem();
  3. FragmentStatePagerAdapter fspa = (FragmentStatePagerAdapter)adapter;
  4. Fragment currentFragment = fspa.getItem(fragmentIndex);

Обычно используется только литая строка 3. FragmentStatePagerAdapter является полезным адаптером для ViewPager.

5
ответ дан Robert 19 August 2018 в 15:09
поделиться

Когда мы используем viewPager, хорошим способом доступа к экземпляру фрагмента в активности является instantiateItem (viewpager, index). // индекс-индекс фрагмента, который вы хотите использовать.

Например, я обращаюсь к экземпляру фрагмента из 1 index-

Fragment fragment = (Fragment) viewPageradapter.instantiateItem(viewPager, 1);

if (fragment != null && fragment instanceof MyFragment) {      
 ((MyFragment) fragment).callYourFunction();

}
1
ответ дан Royz 19 August 2018 в 15:09
поделиться

FragmentStatePagerAdapter имеет переменную частного экземпляра, называемую mCurrentPrimaryItem типа Fragment. Можно только задаться вопросом, почему разработчики Android не предоставили его с помощью геттера. Эта переменная создается в setPrimaryItem() методе. Таким образом, переопределите этот метод таким образом, чтобы вы могли получить ссылку на эту переменную. Я просто закончил с объявлением своего mCurrentPrimaryItem и копированием содержимого setPrimaryItem() в мое переопределение.

В вашей реализации FragmentStatePagerAdapter:

private Fragment mCurrentPrimaryItem = null;

@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
    Fragment fragment = (Fragment)object;
    if (fragment != mCurrentPrimaryItem) {
        if (mCurrentPrimaryItem != null) {
            mCurrentPrimaryItem.setMenuVisibility(false);
            mCurrentPrimaryItem.setUserVisibleHint(false);
        }
        if (fragment != null) {
            fragment.setMenuVisibility(true);
            fragment.setUserVisibleHint(true);
        }
        mCurrentPrimaryItem = fragment;
    }
}

public TasksListFragment getCurrentFragment() {
    return (YourFragment) mCurrentPrimaryItem;
}
1
ответ дан Sevastyan 19 August 2018 в 15:09
поделиться

Это более надежное будущее, чем принятый ответ:

public class MyFragmentPagerAdapter extends FragmentPagerAdapter {

    /* ------------------------------------------------------------------------------------------ */
    // region Private attributes :

    private Context _context;
    private FragmentManager _fragmentManager;
    private Map<Integer, String> _fragmentsTags = new HashMap<>();

    // endregion
    /* ------------------------------------------------------------------------------------------ */



    /* ------------------------------------------------------------------------------------------ */
    // region Constructor :

    public MyFragmentPagerAdapter(Context context, FragmentManager fragmentManager) {

        super(fragmentManager);

        _context = context;
        _fragmentManager = fragmentManager;
    }

    // endregion
    /* ------------------------------------------------------------------------------------------ */



    /* ------------------------------------------------------------------------------------------ */
    // region FragmentPagerAdapter methods :

    @Override
    public int getCount() { return 2; }

    @Override
    public Fragment getItem(int position) {

        if(_fragmentsTags.containsKey(position)) {

            return _fragmentManager.findFragmentByTag(_fragmentsTags.get(position));
        }
        else {

            switch (position) {

                case 0 : { return Fragment.instantiate(_context, Tab1Fragment.class.getName()); }
                case 1 : { return Fragment.instantiate(_context, Tab2Fragment.class.getName()); }
            }
        }

        return null;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {

        // Instantiate the fragment and get its tag :
        Fragment result = (Fragment) super.instantiateItem(container, position);
        _fragmentsTags.put(position, result.getTag());

        return result;
    }

    // endregion
    /* ------------------------------------------------------------------------------------------ */
}
1
ответ дан Tim Autin 19 August 2018 в 15:09
поделиться

Это самый простой взлом:

fun getCurrentFragment(): Fragment? {
    return if (count == 0) null
    else instantiateItem(view_pager, view_pager.currentItem) as? Fragment
}

(код kotlin)

Просто вызовите instantiateItem(viewPager, viewPager.getCurrentItem() и переведите его в Fragment. Ваш объект уже будет создан. Чтобы убедиться, что вы можете добавить проверку для getCount.

Работает как с FragmentPagerAdapter, так и с FragmentStatePagerAdapter!

0
ответ дан vedant 19 August 2018 в 15:09
поделиться

Если ваш пейджер находится внутри фрагмента, используйте это:

private fun getPagerCurrentFragment(): Fragment? {
    return childFragmentManager.findFragmentByTag("android:switcher:${R.id.myViewPagerId}:${myViewPager.currentItem}")
}

Где R.id.myViewPagerId - это идентификатор вашего ViewPager внутри макета xml.

0
ответ дан vovahost 19 August 2018 в 15:09
поделиться
  • 1
    Это работает только с обычным FragmentPagerAdapter, а не с FragmentStatePagerAdapter. – progNewbie 15 August 2018 в 14:33

Этот сценарий лучше всего обслуживает каждый фрагмент, добавляя свои собственные пункты меню и непосредственно обрабатывая onOptionsItemSelected (), как описано в официальной документации . Лучше избегать недокументированных трюков.

1
ответ дан Y2i 19 August 2018 в 15:09
поделиться
  • 1
    В этом ответе можно было бы более подробно описать, как это сделать. Как добавить пункт меню для решения проблемы ViewPager? – Suragch 6 December 2016 в 07:21
  • 2
    Проблема @Suragch ViewPager существует, если события меню обрабатываются внутри Activity, которые содержат фрагменты и не существуют, если события обрабатываются внутри самого фрагмента. Ссылка показывает, как фрагмент может добавлять свои собственные пункты меню. – Y2i 3 November 2017 в 01:28

Основываясь на том, что он ответил @chahat jain:

«Когда мы используем viewPager, хорошим способом доступа к экземпляру фрагмента в активности является instantiateItem (viewpager, index). // index-index of фрагмент которого вам нужен. "

Если вы хотите сделать это в kotlin

val fragment =  mv_viewpager.adapter!!.instantiateItem(mv_viewpager, 0) as Fragment
                if ( fragment is YourFragmentFragment)
                 {
                    //DO somthign 
                 }

0 на экземпляр фрагмента 0

// = ================================================== ====================== // // ######################## ##### Пример использования ################################## // // ===== ================================================== ================== // //

Вот полный пример, чтобы получить самое лёгкое видение

.xml file

   ...
    <android.support.v4.view.ViewPager
                android:id="@+id/mv_viewpager"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_margin="5dp"/>
    ...

И домашняя активность, в которую я вставляю вкладку

...
import kotlinx.android.synthetic.main.movie_tab.*

class HomeActivity : AppCompatActivity() {

    lateinit var  adapter:HomeTabPagerAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
       ...
    }



    override fun onCreateOptionsMenu(menu: Menu) :Boolean{
            ...

        mSearchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
          ...

            override fun onQueryTextChange(newText: String): Boolean {

                if (mv_viewpager.currentItem  ==0)
                {
                    val fragment =  mv_viewpager.adapter!!.instantiateItem(mv_viewpager, 0) as Fragment
                    if ( fragment is ListMoviesFragment)
                        fragment.onQueryTextChange(newText)
                }
                else
                {
                    val fragment =  mv_viewpager.adapter!!.instantiateItem(mv_viewpager, 1) as Fragment
                    if ( fragment is ListShowFragment)
                        fragment.onQueryTextChange(newText)
                }
                return true
            }
        })
        return super.onCreateOptionsMenu(menu)
    }
        ...

}
1
ответ дан ZINA TAKLIT 19 August 2018 в 15:09
поделиться

Прежде всего, отслеживайте все «активные» фрагменты. В этом случае вы отслеживаете страницы фрагментов в FragmentStatePagerAdapter, которые используются ViewPager.

@Override
public Fragment getItem(int index) {
    Fragment myFragment = MyFragment.newInstance();
    mPageReferenceMap.put(index, myFragment);
    return myFragment;
}

Чтобы избежать ссылки на «неактивные» фрагментные страницы, вам необходимо реализовать FragmentStatePagerAdapter destroyItem (...):

@Override
public void destroyItem (ViewGroup container, int position, Object object) {
    super.destroyItem(container, position, object);
    mPageReferenceMap.remove(position);
}

, и когда вам нужно получить доступ к отображаемой в данный момент странице, вы вызываете:

int index = mViewPager.getCurrentItem();
MyAdapter adapter = ((MyAdapter)mViewPager.getAdapter());
MyFragment fragment = adapter.getFragment(index);

Где getFragment (int) MyAdapter метод выглядит следующим образом:

public MyFragment getFragment(int key) {
    return mPageReferenceMap.get(key);
}

Надеюсь, это поможет!

101
ответ дан Zon 19 August 2018 в 15:09
поделиться
  • 1
    Не могли бы вы объяснить это? Где мне нужно сохранить класс FragmentStatePagerAdapter в моем коде? BTW У меня есть 3 класса фрагментов, а не один MyFragmentClass. – rick 4 September 2013 в 10:36
  • 2
    Еще лучше, если вы обновите mPageReferenceMap в instantiateItem вместо getItem, потому что он также работает после изменения ориентации. '@Override public Object instantiateItem (контейнер ViewGroup, позиция int) {Фрагмент фрагмента = (фрагмент) Super.instantiateItem (контейнер, позиция); mPageReferenceMap.put (позиция, фрагмент); возвратный фрагмент; }» – pmellaaho 13 February 2014 в 09:25
  • 3
    Этот ответ действительно плохой! Вы не должны хранить кеш ViewPager вручную, так как он обрабатывает его сам по себе. ViewPager решает, когда фрагмент должен быть выделен или нет, что делать паузу и когда сохранение ссылки на каждый фрагмент добавит некоторые бесполезные служебные данные и не оптимизируется для памяти. – Livio 6 November 2015 в 16:17
  • 4
    Не работает после перезагрузки – Marcos Vasconcelos 8 November 2017 в 20:06
  • 5
    Я пробовал этот подход, но, к сожалению, он не работает, когда активность воссоздана. В Android N и более поздних версиях это можно увидеть при использовании функции multiwindow. Когда ваше приложение открыто, долго удерживайте кнопку «recents» (квадрат). Активность и фрагмент воссоздаются из savedInstanceState, адаптер воссоздается (поэтому mPageReferenceMap теперь пуст), но getItem не вызывается снова. Карта остается пустым, так что адаптер.getFragment (index) выйдет из строя. – Martin Konicek 11 January 2018 в 12:30

Это единственный способ, которым я не получаю исключение NullPointerException для переменных экземпляра этих классов фрагментов. Это может быть полезно для других, которые придерживаются одного и того же. В onOptionsItemSelected () я закодировал ниже:

if(viewPager.getCurrentItem() == 0) {
    FragmentClass1 frag1 = (FragmentClass1)viewPager
                            .getAdapter()
                            .instantiateItem(viewPager, viewPager.getCurrentItem());
    frag1.updateList(text); 
} else if(viewPager.getCurrentItem() == 1) {
    FragmentClass2 frag2 = (FragRecentApps)viewPager
                            .getAdapter()
                            .instantiateItem(viewPager, viewPager.getCurrentItem());
    frag2.updateList(text);
}
73
ответ дан ZooMagic 19 August 2018 в 15:09
поделиться
  • 1
    Я думаю, что это самый правильный ответ - выровняйтесь с дизайном FragmentStatePagerAdapter без переопределения какого-либо кода. Фактически, это должно быть так просто, как только функция возвращает viewPager.getAdapter().instantiateItem(viewPager, viewPager.getCurrentItem()). – John Pang 30 December 2016 в 18:44
  • 2
    недооцененный ответ – PrisonMike 19 December 2017 в 17:11
  • 3
    На самом деле это отличный ответ. – moxi 4 February 2018 в 08:02
2
ответ дан Ritesh Adulkar 31 October 2018 в 02:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: