I have sample project with TabLayout
and PagerAdapter
.
Strange things happens with TabLayout when I call pagerAdapter.notifyDataSetChanged();
after tabLayout.setupWithViewPager(viewPager);
TabLayout is scrolling to unknown x position so the current tab is not visible. However if I scroll to left to expecting tab, this tab has indicator.
What is going on? Could anyone help me? I have spent on it too many time.
Below the code.
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Get the ViewPager and set it's PagerAdapter so that it can display items
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
final SampleFragmentPagerAdapter pagerAdapter = new SampleFragmentPagerAdapter(getSupportFragmentManager(), MainActivity.this);
viewPager.setAdapter(pagerAdapter);
// Give the TabLayout the ViewPager
TabLayout tabLayout = (TabLayout) findViewById(R.id.sliding_tabs);
tabLayout.setupWithViewPager(viewPager);
findViewById(R.id.fab).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pagerAdapter.notifyDataSetChanged();
}
});
}
}
I tested on nexus emulators and nexus real devices (api 21+)
Gradle settings:
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "xx.xxx.myapplication4"
minSdkVersion 21
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
Link to reported issue and ready to test project as attachment here
You can call:
and set param
autoRefresh
tofalse
.See also:
TabLayout(ViewPager,boolean)
Every time setup view pager with the use of
setupWithViewPager
might be costly. BecausenotifyDataSetChanged()
on your ViewPager Adapter causing TabLayout to redraw its all views. So for redrawing,TabLayout
remove all its associatedViews
and re add them.Please check below thread execution steps which happen after
notifyDataSetChanged
on pager adapter.According to thread execution -
Clicked on Action Button > Pager Adapter Notified for data set changed > TabLayout got notification of data change through observers > It try to populate new data from adapter > Removed all tabs.
Below is a code of
TabLayout
class, from which you can check whenever all tabs are going to remove then last selected tab is lost(Intentionally marked null).To retain last selected tab I have created my own CustomTabLayout class and retained last selected position.
At the end make sure to reselect your tab after recreation of your
TabLayout
.This issue will resolve your problem but what I believe is
TabLayout
must have to retain last selected position in case of data set change. This is what I understand, any comments or more understanding is welcome.I just added notifyDataSetChanged method inside of TabLayout implementation of Rasi.
It works for me.
and to notify call
I fix the issue, you need modify the TabLayout source code
I guess I found solution just by reordering call methods when notifyDataSetChanged
you can directly set the current postion.
you can get the selected position before notifying dataset change and save it in static varaible and update it everytime:
below is the code from my project :