Hello everybody i have a problem with my android app. I tried hard to understand it but i cannot completely understand, how much to find a solution.I have my main activity with a viewpager2 and FragmentStateAdapter, additionally i have a tablayout. My app works just fine if it starts in portrait or if it starts in landscape. On orientation change though things are getting messy. More specifically after the orientation change when i try to reference a view on my fragments a null reference exception is thrown. My fragments are built with layout variation through the editor. Another detail is that fragments are dynamically added. A possible explanation may be that after orientation change the main activity along with the fragments are being recreated, hence their views/layout are displayed but in reality the support manager still holds the id of the fragments before the orientation change. Sorry if my explanation lacks and thanks in advance for any possible advice on the matter.
MAIN ACTIVITY
public class MainActivity extends BaseActivity implements View.OnClickListener , EnterDataFragment.NotifyActivity {
MainFragmentsAdapter pagerAdapter;
ViewPager2 viewPager;
TabLayout tabs;
TabLayoutMediator tabLayoutMediator;
String[] titles = {"Enter Data" , "Results" };
ExpandableFabLayout fabLayout;
FabOption clearFab;
FabOption calculateFab;
EnterDataFragment dataFragment;
ResultsFragment resultsFragment;
private int shortAnimationDuration;
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SetupViews();
SetUpAdapter();
tabLayoutMediator = new TabLayoutMediator(tabs, viewPager, new TabLayoutMediator.TabConfigurationStrategy() {
@Override
public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
//position of the current tab and the tab
tab.setText(titles[position]) ;
viewPager.setCurrentItem(position, true);
}
});
tabLayoutMediator.attach();
viewPager.setCurrentItem(0,true);
tabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
if(tab.getPosition() == 1 ){
fabLayout.animate()
.alpha(0f)
.setDuration(shortAnimationDuration)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
fabLayout.setVisibility(View.INVISIBLE);
}
});
//fabLayout.setVisibility(View.INVISIBLE);
}
else{
fabLayout.setAlpha(0f);
fabLayout.setVisibility(View.VISIBLE);
fabLayout.animate()
.alpha(1f)
.setDuration(shortAnimationDuration)
.setListener(null);
}
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
private void SetupViews(){
viewPager = findViewById(R.id.viewPager);
tabs = findViewById(R.id.tabLayout);
fabLayout = findViewById(R.id.expandable_fab_layout);
clearFab = findViewById(R.id.fabClear);
clearFab.setOnClickListener(this);
calculateFab = findViewById(R.id.fabCalculate);
calculateFab.setOnClickListener(this);
shortAnimationDuration = getResources().getInteger(android.R.integer.config_shortAnimTime);
}
private void SetUpAdapter(){
dataFragment = new EnterDataFragment();
dataFragment.AttachListener(this);
resultsFragment = new ResultsFragment();
pagerAdapter = new MainFragmentsAdapter(getSupportFragmentManager(),getLifecycle());
pagerAdapter.clearList();
pagerAdapter.addFragment(dataFragment);
pagerAdapter.addFragment(resultsFragment);
viewPager.setAdapter(pagerAdapter);
}
private void ClearAllFields(){
dataFragment.ClearAllFields();
}
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.fabClear:
Toast.makeText(this,"CLEAR",Toast.LENGTH_LONG);
ClearAllFields();
break;
case R.id.fabCalculate:
gatherInputs();
break;
}
}
private void gatherInputs(){
dataFragment.GatherInputs();
}
@Override
public void DatasetLoaded(List<AquachronStage> dataset) {
resultsFragment.UpdateDataset(dataset);
}
@Override
protected void setUpView() {
}
@Override
protected void InitializePresenter() {
}
}
ADAPTER
public class MainFragmentsAdapter extends FragmentStateAdapter {
private ArrayList<Fragment> fragmentList = new ArrayList<>();
public MainFragmentsAdapter(@NonNull FragmentManager fragmentActivity, Lifecycle lifecycle) {
super(fragmentActivity,lifecycle);
}
@NonNull
@Override
public Fragment createFragment(int position) {
return fragmentList.get(position);
}
@Override
public int getItemCount() {
return fragmentList.size();
}
public void addFragment(Fragment fragment) {
fragmentList.add(fragment);
}
public void clearList(){
for (Fragment fr: fragmentList
) {
fragmentList.remove(fr);
notifyItemRemoved(fragmentList.indexOf(fr));
}
}
@Override
public long getItemId(int position) {
return super.getItemId(position);
}
}