I am developing an android weather application that includes a Tablelayout with 3 pages. The adapter is a FragmentStatePagerAdaptater and in each of them is a Fragment that contains a RecyclerView. The application receives and processes the weather datas in an asynctask and then updates the ViewPager with the received datas.
My question is to know that it is the best practice when initializing the ViewPager, ie, I initialize the ViewPager in my MainActivity OnCreate() with empty datas in Fragment because I do not yet have the weather datas at this moment. Once the data received I notify the ViewPager that the datas has changed and then in the FragmentStatePagerAdapter in getItemPosition() method I perform the update of the RecyclerView of the fragments. The RecyclerView are updated with a method equivalent of a contrustor that pass the new datas in the RecyclerViewAdaptater and a notifyDataSetChanged() to notify that the data has changed.
But maybe a best practice would be to wait for receiving the weather datas and then initialize the Viewpager adapter with the datas. After if the user requests a data updates only notify the ViewPager that the data has changed as is already the case in my application.
This is the code of my approach :
MainActivity OnCreate() :
viewPager = (ViewPager)findViewById(R.id.viewpager);
viewPager.setOffscreenPageLimit(2);
SampleFragmentPagerAdapter adapter = new SampleFragmentPagerAdapter(getSupportFragmentManager());
adapter.addFrag(PageFragment.newInstance(0), "today");
adapter.addFrag(PageFragment.newInstance(1), "tomorrow");
adapter.addFrag(PageFragment.newInstance(2), "7 days");
viewPager.setAdapter(adapter);
Asynctask onPostExecute(Climat climat)
mSwipeRefreshLayout.setRefreshing(false);
if (climat != null) {
MainActivity.climat = climat;
viewPager.getAdapter().notifyDataSetChanged();
// Set page 1
viewPager.setCurrentItem(0);
}
FragmentStatePagerAdaptater :
class SampleFragmentPagerAdapter extends FragmentStatePagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>(3);
private final List<String> mFragmentTitleList = new ArrayList<>(3);
SampleFragmentPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
// Returns total number of pages
@Override
public int getCount() {
return mFragmentList.size();
}
// Returns the fragment to display for that page
@Override
public Fragment getItem(int position) {
Log.i(TAG, "Fragment getItem position " + position);
return mFragmentList.get(position);
}
void addFrag(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
// Refresh fragment
@Override
public int getItemPosition(Object object) {
PageFragment f = (PageFragment ) object;
if (f != null) {
f.update();
}
return super.getItemPosition(object);
}
// Returns the page title for the top indicator
@Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
return mFragmentTitleList.get(position);
}
}
PageFragment :
public class PageFragment extends Fragment implements Updateable {
private static final String ARG_PAGE = "ARG_PAGE";
private int mPage;
private Climat climat = null;
private RecyclerView rv1;
private RecyclerView rv2;
private RecyclerView rv3;
private ClimatAdaptateurToday climatAdaptateurTodayRv1;
private ClimatAdaptateurToday climatAdaptateurTodayRv2;
private ClimatAdaptateur climatAdaptateur;
// newInstance constructor for creating fragment with arguments
public static PageFragment newInstance(int page) {
PageFragment fragment = new PageFragment();
// Supply num input as an argument.
Bundle args = new Bundle();
args.putInt(ARG_PAGE, page);
fragment.setArguments(args);
return fragment;
}
/**
* When creating, retrieve this instance's number from its arguments.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPage = getArguments() != null ? getArguments().getInt(ARG_PAGE) : 0;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
switch (mPage) {
case 0:
rv1 = (RecyclerView) view.findViewById(R.id.recyclerView);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
rv1.setHasFixedSize(true);
// use a linear layout manager
RecyclerView.LayoutManager layoutRv1 = new LinearLayoutManager(getActivity());
rv1.setLayoutManager(layoutRv1);
rv1.setItemAnimator(new DefaultItemAnimator());
climatAdaptateurTodayRv1 = new ClimatAdaptateurToday(climat, mPage);
climatAdaptateurTodayRv1.setHasStableIds(true);
rv1.setAdapter(climatAdaptateurTodayRv1);
break;
case 1:
rv2 = (RecyclerView) view.findViewById(R.id.recyclerView);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
rv2.setHasFixedSize(true);
// use a linear layout manager
RecyclerView.LayoutManager layoutRv2 = new LinearLayoutManager(getActivity());
rv2.setLayoutManager(layoutRv2);
rv2.setItemAnimator(new DefaultItemAnimator());
climatAdaptateurTodayRv2 = new ClimatAdaptateurToday(climat, mPage);
climatAdaptateurTodayRv2.setHasStableIds(true);
rv2.setAdapter(climatAdaptateurTodayRv2);
break;
case 2:
rv3 = (RecyclerView) view.findViewById(R.id.recyclerView);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
rv3.setHasFixedSize(true);
// use a linear layout manager
RecyclerView.LayoutManager layoutRv3 = new LinearLayoutManager(getActivity());
rv3.setLayoutManager(layoutRv3);
rv3.setItemAnimator(new DefaultItemAnimator());
climatAdaptateur = new ClimatAdaptateur(null,
null, null);
climatAdaptateur.setHasStableIds(true);
rv3.setAdapter(climatAdaptateur);
break;
}
}
// Inflate the view for the fragment based on layout XML
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.content_main, container, false);
}
// To update fragment in ViewPager, we should implement a public method for the fragment,
// and do updating stuff in this method.
@Override
public void update() {
this.climat = MainActivity.climat;
if (climat != null) {
switch (mPage) {
case 0:
climatAdaptateurTodayRv1.updateData(climat, mPage);
climatAdaptateurTodayRv1.notifyDataSetChanged();
rv1.smoothScrollToPosition(0);
break;
case 1:
climatAdaptateurTodayRv2.updateData(climat, mPage);
climatAdaptateurTodayRv2.notifyDataSetChanged();
rv2.smoothScrollToPosition(0);
break;
case 2:
climatAdaptateur.updateData(climat.getClimatInfoDailyArray(),
climat.getTempsArray(), climat.getLieux());
climatAdaptateur.notifyDataSetChanged();
rv3.smoothScrollToPosition(0);
break;
}
}
}
}
interface Updateable {
void update();
}
Thanks for your help !!