onViewCreated 仅在首次创建 Fragments 时调用。 ViewPager 不会更改 Fragments 的状态。你可以想象隐藏的Fragments 被存储在当前可见的Fragment 的两侧,可见。
我通过在TabLayout 更改时设置回调来完成。 TabLayout 是监听器所在的位置。然后你可以让它在你的FragmentPagerAdapter 中调用一个回调方法。在每个Fragment 中,您应该实现一个返回回调的方法。在FragmentPagerAdapter 中,使用getItem(int position) 将来自Fragment 的回调存储在Map 中。适配器中的回调方法从TabLayout中获取位置
首先,在您的 Fragments 中,为它们提供一个方法,该方法返回某种回调(我使用了 Runnable),该回调将从适配器中调用。
public class PlaceHolderFragment extends Fragment {
...
public Runnable getOnTabChangedListener() {
return new Runnable() {
@Override
public void run() {
scrollView.smoothScrollTo(0, 0);
}
};
}
...
}
然后,在您的FragmentPagerAdapter(我叫我的SectionsPagerAdapter)中,将回调存储在getItem() 方法中的映射中,然后添加自定义回调。
public class SectionsPagerAdapter extends FragmentPagerAdapter {
...
HashMap<Integer, Runnable> tabChangedCallbacks = new HashMap<>();
...
@Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class below).
PlaceholderFragment fragment = PlaceholderFragment.newInstance(position + 1);
tabChangedCallbacks.put(position, fragment.getOnTabChangedListener());
return fragment;
}
public void onTabChanged(int position) {
tabChangedCallbacks.get(position).run();
}
...
}
在包含 TabLayout 的 Activity 中,您需要在 onCreate() 方法中对 TabLayout 调用 addOnTabSelectedListener()。
protected void onCreate(Bundle savedInstanceState) {
...
final SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager());
final ViewPager viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(sectionsPagerAdapter);
TabLayout tabs = findViewById(R.id.tabs);
tabs.setupWithViewPager(viewPager);
tabs.addOnTabSelectedListener(
new TabLayout.ViewPagerOnTabSelectedListener(viewPager) {
@Override
public void onTabSelected(TabLayout.Tab tab) {
super.onTabSelected(tab);
sectionsPagerAdapter.onTabChanged(tab.getPosition());
}
});
...
}
编辑
原理是一样的,但要使用ViewPager2 和FragmentStateAdapter,您需要进行以下更改:
Fragment 保持不变。
适配器在功能上是相同的,但有一些更新的方法:
public class SectionsStateAdapter extends FragmentStateAdapter {
HashMap<Integer, Runnable> tabChangedCallbacks = new HashMap<>();
...
public void onTabChanged(int position) {
tabChangedCallbacks.get(position).run();
}
@NonNull
@Override
public Fragment createFragment(int position) {
PlaceholderFragment fragment = PlaceholderFragment.newInstance(position + 1);
tabChangedCallbacks.put(position, fragment.getOnTabChangedListener());
return fragment;
}
@Override
public int getItemCount() {
return 2;
}
...
}
活动变化最大:
public class MainActivity extends AppCompatActivity {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
...
final SectionsStateAdapter sectionsStateAdapter = new SectionsStateAdapter(this);
final ViewPager2 viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(sectionsStateAdapter);
TabLayout tabs = findViewById(R.id.tabs);
// connect the TabLayout to the ViewPager2
new TabLayoutMediator(tabs, viewPager, new TabLayoutMediator.TabConfigurationStrategy() {
@Override
public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
// set tab text, etc
}
}).attach();
// set the change listener on the ViewPager2
viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
sectionsStateAdapter.onTabChanged(position);
}
});
...
}
}
请注意,唯一真正的变化是 ViewPager2 不需要 TabLayout 来处理页面更改。如果您愿意,您仍然可以使用TabLayout.addOnTabSelectedListener(),但您必须实现自己的TabLayout.OnTabSelecterListener,因为TabLayout.ViewPagerOnTabSelectedListener 不适用于ViewPager2。
例如:
tabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
sectionsStateAdapter.onTabChanged(tab.getPosition());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});