Как я могу установить тег для фрагментов viewpager?

I, m, используя slideTabLayout с 4 вкладками и viewpager и 4 класса фрагмента для каждой вкладки.

мне нужно перезагрузить один из моих фрагментов (первая вкладка) в моем проекте, когда пользователь нажимает кнопку, и для этого мне нужно иметь тег для этого фрагмента

мой вопрос: как я могу установить тег для одного из фрагментов viewpagers???

Моя вкладка MainActivity и код viewpager:

public class MainActivity extends AppCompatActivity
    implements NavigationView.OnNavigationItemSelectedListener {



Toolbar toolbar;
ViewPager pager;
ViewPagerAdapter adapter;
SlidingTabLayout tabs;
CharSequence Titles[]={"نوع","قیمت","برند","همه"};
int Numboftabs = 4;




@Override
protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
}



@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);




    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Snackbar.make(view, "درج آگهی رایگان", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
        }
    });



    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);




    // Creating The ViewPagerAdapter and Passing Fragment Manager, Titles fot the Tabs and Number Of Tabs.
    adapter =  new ViewPagerAdapter(getSupportFragmentManager(),Titles,Numboftabs);

    // Assigning ViewPager View and setting the adapter
    pager = (ViewPager) findViewById(R.id.pager);
    pager.setAdapter(adapter);

    // Assiging the Sliding Tab Layout View
    tabs = (SlidingTabLayout) findViewById(R.id.tabs);
    tabs.setDistributeEvenly(true); // To make the Tabs Fixed set this true, This makes the tabs Space Evenly in Available width

    // Setting Custom Color for the Scroll bar indicator of the Tab View
    tabs.setCustomTabColorizer(new SlidingTabLayout.TabColorizer() {
        @Override
        public int getIndicatorColor(int position) {
            return getResources().getColor(R.color.colorWhite);
        }
    });

    // Setting the ViewPager For the SlidingTabsLayout
    tabs.setViewPager(pager);
    pager.setCurrentItem(3);




} and ....

Большое спасибо

Ответ 1

Для этого есть несколько решений.

1). Когда FragmentPagerAdapter добавляет Fragment в FragmentManager, он использует специальный тег, основанный на конкретной позиции, в которой будет размещен Fragment. Таким образом, вы можете просто получить текущий видимый Fragment в вашем ViewPager используя эти строки кода

 Fragment fragment = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":" + ViewPager.getCurrentItem());
 // based on the current position you can then cast the page to the correct Fragment class and call some method inside that fragment to reload the data:
 if (0 == ViewPager.getCurrentItem() && null != fragment) {
      ((TabFragment1)fragment).reloadFragmentData();     
 } 

2). Вы должны следить за всеми активными фрагментами в FragmentStatePagerAdapter. Для демо-примера вы можете обратиться к второму подходу здесь

3). Вы можете использовать EventBus для публикации событий в своем Fragment из любого места. Все, что вам нужно сделать, это зарегистрировать свой Fragment для этого конкретного события. Для официальной документации см. Это

Ответ 2

Вот метод, который используется FragmentPagerAdapter для создания имени тега Fragment:

private static String makeFragmentName(int viewId, long id) {
    return "android:switcher:" + viewId + ":" + id;
}

viewId - это идентификатор ViewPager.
id - это положение фрагмента внутри ViewPager.

Пример:

String fragmentTag = makeFragmentName(myViewPager.getId(), 2);
Fragment fragment = getSupportFragmentManager().findFragmentByTag(fragmentTag);

Ответ 3

Хотя на этот вопрос уже был дан ответ. У меня есть другой подход к достижению этого, и это может быть лучше, поскольку изменения фрагментов в коде подвергаются изменениям. Также указывать, что using adapter.getItem(position) не возвращает экземпляр отображаемого фрагмента, это будет зависеть от нашей собственной реализации метода getItem.

В основном проблема заключается в том, что у нас нет экземпляра фрагментов, присутствующих в viewPager. Идея заключается в переопределении метода

public Object instantiateItem(ViewGroup container, int position) {
    // If we already have this item instantiated, there is nothing
    // to do.  This can happen when we are restoring the entire pager
    // from its saved state, where the fragment manager has already
    // taken care of restoring the fragments we previously had instantiated.
    if (mFragments.size() > position) {
        Fragment f = mFragments.get(position);
        if (f != null) {
            return f;
        }
    }

    if (mCurTransaction == null) {
        mCurTransaction = mFragmentManager.beginTransaction();
    }

    Fragment fragment = getItem(position);
    if (DEBUG) Log.v(TAG, "Adding item #" + position + ": f=" + fragment);
    if (mSavedState.size() > position) {
        Fragment.SavedState fss = mSavedState.get(position);
        if (fss != null) {
            fragment.setInitialSavedState(fss);
        }
    }
    while (mFragments.size() <= position) {
        mFragments.add(null);
    }
    fragment.setMenuVisibility(false);
    fragment.setUserVisibleHint(false);
    mFragments.set(position, fragment);
    mCurTransaction.add(container.getId(), fragment);

    return fragment;
}

FragmentStatePagerAdapter. Если мы посмотрим на реализацию этого метода по умолчанию, он в основном выполняет задачу создания экземпляров новых фрагментов, если они не существуют и не возвращают их. Также он хранит их в списке фрагментов, которые являются частными. Итак, что мы можем сделать, это переопределить этот метод и сохранить экземпляры на фрагментах в нашем собственном списке. Это можно реализовать следующим образом

private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {

    private ArrayList<Fragment> fragmentList;

    private final int NUM_PAGES;

    public ScreenSlidePagerAdapter(FragmentManager fm, int numPages) {
        super(fm);
        NUM_PAGES = numPages;
        fragmentList = new ArrayList<>(NUM_PAGES);
    }

    @Override
    public Fragment getItem(int position) {
        Fragment fragment = new CustomFragment();
        //this method can be modified according to the requirement
        return fragment;
    }

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

    public Fragment getFragment(int position){
        return fragmentList.get(position);
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position){
        Fragment fragment = (Fragment) super.instantiateItem(container,position);
        if(fragmentList.size()<NUM_PAGES&&!fragmentList.contains(fragment)){
            fragmentList.add(fragment);
        }
        return fragment;
    }
}

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