带有 ViewPager 的 TabLayout 未按预期工作
TabLayout with ViewPager not working as expected
我的申请中有 3 个 TabLayout
和 ViewPager
。
如果我滑动以更改选项卡,那么它 的行为会很奇怪。
场景如下。
假设有 3 个选项卡 A、B、C。
启动应用程序时将打开默认选项卡 A。
从 A 转到 B - 工作正常。
从 B 转到 A - 工作正常。
从 A 转到 B - 工作正常。
从 B 转到 C - 工作正常。
现在问题从这里开始。
从 C 转到 B - 它会加载 A 和 B,但只显示 B。
Why A and B loads if I come from C ??
下面是我的代码。
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
ViewPagerAdapter adapter;
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
private void setupViewPager(ViewPager viewPager) {
adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new FragmentOpen(), "OPEN");
adapter.addFragment(new FragmentClose(), "CLOSE");
adapter.addFragment(new FragmentTest(), "TEST");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
我想每次都加载标签。
为此,我使用以下代码。
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
if(adapter != null){
adapter.getItem(position).onResume();
}
Toast.makeText(getApplicationContext(), "Page Selected", Toast.LENGTH_LONG).show();
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
但当我来自 C 时,它总是会加载两个选项卡。
What I want is: only Tab B must load when came from C, not Both.
使用 ViewPager
时不可能。 ViewPager
根据您的滑动方向至少加载 one
right/left adjacent
个片段 current
个片段。
如果你阅读ViewPager
文档,有一个方法ViewPager.setOffscreenPageLimit(LIMIT)
支持屏幕外页面限制,它的default
值是1
。
SetOffscreenPageLimit:
Set the number of pages that should be retained to either side of the
current page in the view hierarchy in an idle state. Pages beyond this
limit will be recreated from the adapter when needed.
This is offered as an optimization. If you know in advance the number
of pages you will need to support or have lazy-loading mechanisms in
place on your pages, tweaking this setting can have benefits in
perceived smoothness of paging animations and interaction. If you have
a small number of pages (3-4) that you can keep active all at once,
less time will be spent in layout for newly created view subtrees as
the user pages back and forth.
You should keep this limit low, especially if your pages have complex
layouts. This setting defaults to 1.
参见 documentation。
以下是一些相关的回答:
1. ViewPager.setOffscreenPageLimit(0) doesn't work as expected
2. How can make my ViewPager load only one page at a time ie setOffscreenPageLimit(0);
3. How does setOffscreenPageLimit() improve ViewPager performance by retaining more offscreen Fragments?
its Default behavior of ViewPager
if you are in A then it loads B
also and when your reach B it will Load C and A also is Loaded now
when to reach at C its destroy the View of A and now when you come
again to B it will Load A again, in a simple way ViewPager
Maintain
the One Next
and One previous
state of View by Default.
要克服这个问题,您应该使用 ViewPager.setOffscreenPageLimit(number)
这里的数字是为下一个和上一个视图模拟加载的页面数。
我只有 3 个选项卡,设置ViewPager.setOffscreenPageLimit(2)
对我有用。
尝试ViewPager.setOffscreenPageLimit(totTabs - 1)
我的申请中有 3 个 TabLayout
和 ViewPager
。
如果我滑动以更改选项卡,那么它 的行为会很奇怪。
场景如下。
假设有 3 个选项卡 A、B、C。
启动应用程序时将打开默认选项卡 A。
从 A 转到 B - 工作正常。
从 B 转到 A - 工作正常。
从 A 转到 B - 工作正常。
从 B 转到 C - 工作正常。
现在问题从这里开始。
从 C 转到 B - 它会加载 A 和 B,但只显示 B。
Why A and B loads if I come from C ??
下面是我的代码。
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
ViewPagerAdapter adapter;
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
private void setupViewPager(ViewPager viewPager) {
adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new FragmentOpen(), "OPEN");
adapter.addFragment(new FragmentClose(), "CLOSE");
adapter.addFragment(new FragmentTest(), "TEST");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
我想每次都加载标签。
为此,我使用以下代码。
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
if(adapter != null){
adapter.getItem(position).onResume();
}
Toast.makeText(getApplicationContext(), "Page Selected", Toast.LENGTH_LONG).show();
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
但当我来自 C 时,它总是会加载两个选项卡。
What I want is: only Tab B must load when came from C, not Both.
使用 ViewPager
时不可能。 ViewPager
根据您的滑动方向至少加载 one
right/left adjacent
个片段 current
个片段。
如果你阅读ViewPager
文档,有一个方法ViewPager.setOffscreenPageLimit(LIMIT)
支持屏幕外页面限制,它的default
值是1
。
SetOffscreenPageLimit:
Set the number of pages that should be retained to either side of the current page in the view hierarchy in an idle state. Pages beyond this limit will be recreated from the adapter when needed.
This is offered as an optimization. If you know in advance the number of pages you will need to support or have lazy-loading mechanisms in place on your pages, tweaking this setting can have benefits in perceived smoothness of paging animations and interaction. If you have a small number of pages (3-4) that you can keep active all at once, less time will be spent in layout for newly created view subtrees as the user pages back and forth.
You should keep this limit low, especially if your pages have complex layouts. This setting defaults to 1.
参见 documentation。
以下是一些相关的回答:
1. ViewPager.setOffscreenPageLimit(0) doesn't work as expected
2. How can make my ViewPager load only one page at a time ie setOffscreenPageLimit(0);
3. How does setOffscreenPageLimit() improve ViewPager performance by retaining more offscreen Fragments?
its Default behavior of
ViewPager
if you are in A then it loads B also and when your reach B it will Load C and A also is Loaded now when to reach at C its destroy the View of A and now when you come again to B it will Load A again, in a simple wayViewPager
Maintain the OneNext
and Oneprevious
state of View by Default.
要克服这个问题,您应该使用 ViewPager.setOffscreenPageLimit(number)
这里的数字是为下一个和上一个视图模拟加载的页面数。
我只有 3 个选项卡,设置ViewPager.setOffscreenPageLimit(2)
对我有用。
尝试ViewPager.setOffscreenPageLimit(totTabs - 1)