I have 3 bottom navigation tabs in my application :
- Home
- MyTour
- Profile
In MyTour
, I am using MyTourFragment
which have 3 different tabs :
- Pending(0)
- Success(1)
- Failed(2)
For all three tabs(Pending, Success, Failed) I am using FragmentMyTourJobList
and depend on condition I am showing pending or success or failed data in all three tabs.
Problem statement :
When I click on MyTour
Navigation Item, Pending Fragment instance is coming null and I am only able to see blank fragment but if i click to success or failed then I can see data. Pending tab data is only visible after coming back from other tabs but not initially.
Here is MyTourFragment code :
public class MyTourFragment {
public MyTourFragment() {
}
public static MyTourFragment newInstance(MyTourFragmentListener myTourFragmentListener) {
return new MyTourFragment(myTourFragmentListener);
}
private MyTourFragment(MyTourFragmentListener myTourFragmentListener) {
this.mMyTourFragmentListener = myTourFragmentListener;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mViewModel.setNavigator(this);
setHasOptionsMenu(true);
//Get the Tab Id.
Bundle bundle = this.getArguments();
if (bundle != null) {
mViewModel.setSelectedDateTimeMillis(bundle.getLong("todaysDateForMyTour", Calendar.getInstance().getTimeInMillis()));
mSelectedTabId = bundle.getInt(KEY_SELECTED_TAB, 0);
}
mMyTourJobsListPagerAdapter = new MyTourJobsListPagerAdapter(this, mViewModel.getTourIdForSelectedDate(), this);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mFragmentMyTourBinding = getViewDataBinding();
mFragmentMyTourBinding.vpMyTour.setOffscreenPageLimit(2);
mFragmentMyTourBinding.vpMyTour.setCurrentItem(0);
mFragmentMyTourBinding.vpMyTour.setAdapter(mMyTourJobsListPagerAdapter);
mFragmentMyTourBinding.tabLayoutMyTour.setupWithViewPager(mFragmentMyTourBinding.vpMyTour, true);
mFragmentMyTourBinding.tabLayoutMyTour.addOnTabSelectedListener(this);
setUpTabs();
}
private void setUpTabs() {
//Select the current Tab.
mFragmentMyTourBinding.vpMyTour.setCurrentItem(mSelectedTabId);
//Refresh job list as per the selected date.
FragmentMyTourJobsList fragmentMyTourJobsList = mMyTourJobsListPagerAdapter.getFragmentAtTab(mSelectedTabId); **// this is null first time**
if (fragmentMyTourJobsList != null) {
fragmentMyTourJobsList.refreshJobsList(mViewModel.getTourIdForSelectedDate());
}
}
}
Here is MyTourJobsListPagerAdapter code :
public class MyTourJobsListPagerAdapter extends FragmentStatePagerAdapter {
private static final int MY_TOUR_JOBS_LIST_PAGES_COUNT = 3;
private static final int POSITION_TAB_PENDING = 0;
private static final int POSITION_TAB_SUCCESS = 1;
private static final int POSITION_TAB_FAILED = 2;
private HashMap<Integer, FragmentMyTourJobsList> mTabsFragments = new HashMap<Integer, FragmentMyTourJobsList>();
private long mTourId;
private FragmentMyTourJobsList.FragmentMyTourJobsListListener mFragmentMyTourJobsListListener;
public MyTourJobsListPagerAdapter(Fragment fragment, long tourId, FragmentMyTourJobsList.FragmentMyTourJobsListListener fragmentMyTourJobsListListener) {
super(fragment.getChildFragmentManager(), BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
this.mTourId = tourId;
this.mFragmentMyTourJobsListListener = fragmentMyTourJobsListListener;
}
public void setTourId(long tourId) {
this.mTourId = tourId;
}
@Override
public int getCount() {
return MY_TOUR_JOBS_LIST_PAGES_COUNT;
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
mTabsFragments.put(position, (FragmentMyTourJobsList) fragment);
return fragment;
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
mTabsFragments.remove(position);
super.destroyItem(container, position, object);
}
@Override
public Fragment getItem(int position) {
FragmentMyTourJobsList fragmentMyTourJobsList;
switch (position) {
case POSITION_TAB_SUCCESS:
fragmentMyTourJobsList = getFragmentWithBundle(Constants.JOB_STATUS_SUCCESSFUL);
break;
case POSITION_TAB_FAILED:
fragmentMyTourJobsList = getFragmentWithBundle(Constants.JOB_STATUS_FAILED);
break;
case POSITION_TAB_PENDING:
default:
fragmentMyTourJobsList = getFragmentWithBundle(Constants.JOB_STATUS_ACCEPTED);
break;
}
return fragmentMyTourJobsList;
}
public FragmentMyTourJobsList getFragmentAtTab(int tabPosition) {
return mTabsFragments.get(tabPosition);
}
private FragmentMyTourJobsList getFragmentWithBundle(String jobsStatus) {
FragmentMyTourJobsList fragmentToLoad = FragmentMyTourJobsList.newInstance();
Bundle bundle = new Bundle();
bundle.putString(FragmentMyTourJobsList.KEY_ARG_JOBS_STATUS, jobsStatus);
bundle.putLong(FragmentMyTourJobsList.KEY_ARG_TOUR_ID, mTourId);
bundle.putSerializable(FragmentMyTourJobsList.KEY_ARG_FRAGMENT_MY_TOUR_JOBS_LIST_LISTENER, mFragmentMyTourJobsListListener);
fragmentToLoad.setArguments(bundle);
return fragmentToLoad;
}
}
Everything is working but when i will go to Pending tab first time then it's not working. I am missing anything here?
Added FragmentMytourJobList
public class FragmentMyTourJobsList extends BaseFragment<FragmentMyTourJobsListBinding, MyTourJobsListViewModel> implements MyTourJobsListNavigator {
public static FragmentMyTourJobsList newInstance() {
return new FragmentMyTourJobsList();
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mViewModel.setNavigator(this);
Bundle bundle = this.getArguments();
if (bundle != null) {
mJobsStatus = bundle.getString(KEY_ARG_JOBS_STATUS);
mTourId = bundle.getLong(KEY_ARG_TOUR_ID, 0);
}
}
@Override
public int getBindingVariable() {
return myTourJobsListViewModel;
}
@Override
public int getLayoutId() {
return R.layout.fragment_my_tour_jobs_list;
}
@Override
public MyTourJobsListViewModel getViewModel() {
mViewModel = ViewModelProviders.of(this, new ViewModelProviderFactory(Objects.requireNonNull(getActivity()).getApplication())).get(MyTourJobsListViewModel.class);
return mViewModel;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mFragmentMyTourJobsListBinding = getViewDataBinding();
// fetch job list from database
ArrayList<JobUiModel> jobList = mViewModel.fetchJobs(mTourId, mJobsStatus);
RecyclerView.LayoutManager rvLayoutManager = new LinearLayoutManager(getActivity());
mFragmentMyTourJobsListBinding.rvMyTourJobs.setLayoutManager(rvLayoutManager);
// initialize adapter
mJobsListAdapter = new MyTourJobsListAdapter(getContext(), jobList, mJobsStatus);
mFragmentMyTourJobsListBinding.rvMyTourJobs.setAdapter(mJobsListAdapter);
mJobsListAdapter.setClickInterface(this);
mFragmentMyTourJobsListBinding.rvMyTourJobs.addItemDecoration(new EndOffsetItemDecoration(CommonUtils.dpToPx(56)));
}
void refreshJobsList(long tourId) {
if (tourId > 0) {
mTourId = tourId;
mViewModel.fetchJobs(tourId, mJobsStatus);
// fetch job list from database
ArrayList<JobUiModel> jobList = mViewModel.fetchJobs(mTourId, mJobsStatus);
mJobsListAdapter.setDataset(jobList);
mJobsListAdapter.notifyDataSetChanged();
} else {
mJobsListAdapter.setDataset(null);
mJobsListAdapter.notifyDataSetChanged();
}
}
}