I have 5 fragments in ViewPager
used to fill business object with several fields step by step, in each step some of those fields will be set. I\'ve read many articl
Have you checkout EventBus?
I'm not sure if it is the best approach, specially when your question is too broad, however it will be cool with just 5 fragments.
Hope it helps
While singleton approach seems easy to implement and understand it is way not to best way to achieve what you need. One reason is that your model object or as you call it business object lives outside of your activity's context which can create hard to find bugs. E.g. in case when more than one instance of your activity class is created by system and both keep reference to your singleton. See how you lose track of your objects?
What I would do is
parcelable
now you can easily pass it between fragments, activities, and even save it in shared preferences. One important thing to note here when you pass your parcelable
between fragment or activity it is like pass by value, i.e. every time new instance is created.Set your fragment's argument or if it is already instantiated then get arguments and add your model. here is an example: if a fragment is not active yet:
Bundle args = new Bundle();
args.putParcable("businessObject", yourBusinessObjectThatIsParcable);
yourFragment.setArguments(args);
Otherwise:
yourFragment.getArguments().putParcelable("businessObject", yourBusinessObjectThatIsParcable);
In your fragment perhaps in onCreateView method get your model object like this MyParcableObject mpo = (MyParcableObject)getArguments().getParcelable("businessObject")
and use it set whatever data you want.
When you finish editing your object on button click or in onPause method updated your fragment's arguments same way getArguments().putParcelable("businessObject", mpo);
in your last page or last fragment you can pass your object to your activity, here is how to do it
Even though it looks cumbersome but it is a practice that you need to get used to as an android developer. You get lot more control when your model implements parcelable
.
Another way to do what you need is thru Delegation Pattern but it is mostly used for callbacks even though you can pass objects as well.
you can save your data in onSaveInstanceState() event of the activity in case your process will go into the background. you can restore your data in onCreate() event by using Bundle and getExtras().
you can save your data in application class and the data will still be there in case your process will go into the background.
i prefer the first option because you don't want to make a mess in the application class with all the data from different activities and fragments. I hope i could help :)
Before choosing any option, keep in mind user can navigate or open any other app(s) so you lost your data.
You can use onSaveInstanceState
but it will somehow difficult to maintain (as you said you are new in android). You can go with with singleton by using
SharefPreference
(preferably) - If you want to use single values.In both cases you will create a singleton object and access its properties in your fragments.
I suppose in your MainActivity there is a ViewPager
, and FragmentOne
will be one of the fragments inside the view pager. Here the MainActivity is communicating to the FragmentOne to refreshhis adapter. Hope is clear.
In your MainActivity add this interface:
public interface Updateable {
public void update();
}
Implement this interface in a fragment that needs to be updated, and write the code to notify the adapter inside the update
method:
public class FragmentOne extends Fragment implements MainActivity.Updateable {
...
@Override
public void update() {
// YOUR CODE TO UPDATE HERE, FOR EXAMPLE, HERE I'M UPDATING THE ADAPTER
if ( adapter != null ) {
adapter.notifyDataSetChanged();
} else {
Log.d("LOG_TAG", "null");
}
}
...
}
Call the update
method from the MainActivity when the fragment loads first. You can do this overriding the getItemPosition
method in your PagerAdapter
, like this:
@Override
public int getItemPosition(Object object) {
if ( object != null && object instanceof FragmentOne ) {
FragmentOne f = (FragmentOne) object;
f.update();
}
return super.getItemPosition(object);
}
Finally, you have to call notifyDataSetChanged() of your viewPager adapter. This will force the adapter of your viewpager to call the getItemPosition method.
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
int previousState;
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
if (previousState == ViewPager.SCROLL_STATE_SETTLING && state == ViewPager.SCROLL_STATE_IDLE) {
if ( viewPagerAdapter.getItem(viewpager.getCurrentItem()) instanceof Pictures ) {
Log.d("LOG_TAG", "New Position=" + viewpager.getCurrentItem());
viewPagerAdapter.notifyDataSetChanged();
}
}
previousState = state;
}
});
make your objects parcelable and then pass it to other fragments using bundle. i.e bundle.putParcelable(obj) parcelable is very efficient and fast.
it should motivate you
http://www.developerphil.com/parcelable-vs-serializable/