Skip to content

Commit fe6b40a

Browse files
author
Daniel Novak
committed
Add better support for FragmentStatePagerAdapter
1 parent 3bbdb92 commit fe6b40a

File tree

8 files changed

+84
-22
lines changed

8 files changed

+84
-22
lines changed

library/build.gradle

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ task androidSourcesJar(type: Jar) {
4848

4949
artifacts {
5050
archives androidSourcesJar
51-
archives androidJavadocsJar
5251
}
5352

5453
uploadArchives {
Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,31 @@
11
package eu.inloop.viewmodel;
22

3+
import android.app.Activity;
34
import android.support.annotation.Nullable;
45

6+
import eu.inloop.viewmodel.base.ViewModelBaseActivity;
7+
import eu.inloop.viewmodel.base.ViewModelBaseFragment;
58
import eu.inloop.viewmodel.binding.ViewModelBindingConfig;
69

10+
/**
11+
* Any Activity or Fragment that needs a ViewModel needs to implement this interface.
12+
* You don't need to implement it yourself - use {@link ViewModelBaseActivity} and
13+
* {@link ViewModelBaseFragment} instead.
14+
*/
715
public interface IView {
816
/**
9-
* This method is used for Data Binding to bind correct layout and variable atomatically
17+
* This method is used for Data Binding to bind correct layout and variable automatically
1018
* Can return null value in case that Data Binding is not used.
1119
*
1220
* @return defined ViewModelBinding Config for a specific screen.
1321
*/
1422
@Nullable
1523
ViewModelBindingConfig getViewModelBindingConfig();
24+
25+
/**
26+
* Implement this method to remove the ViewModel associated with the Fragment or Activity.
27+
* This is usually implemented by calling {@link ViewModelHelper#removeViewModel(Activity)},
28+
* see {@link ViewModelBaseActivity#removeViewModel()} and {@link ViewModelBaseFragment#removeViewModel()}.
29+
*/
30+
void removeViewModel();
1631
}

library/src/main/java/eu/inloop/viewmodel/ViewModelHelper.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public void onCreate(@NonNull Activity activity,
7979
if (viewModelWrapper.wasCreated) {
8080
// detect that the system has killed the app - saved instance is not null, but the model was recreated
8181
if (BuildConfig.DEBUG && savedInstanceState != null) {
82-
Log.d("model", "Fragment recreated by system - restoring viewmodel"); //NON-NLS
82+
Log.d("model", "Fragment recreated by system or ViewModelStatePagerAdapter - restoring viewmodel"); //NON-NLS
8383
}
8484
mViewModel.onCreate(arguments, savedInstanceState);
8585
}
@@ -252,7 +252,7 @@ public ViewDataBinding getBinding() {
252252
return mBinding;
253253
}
254254

255-
private void removeViewModel(@NonNull final Activity activity) {
255+
public void removeViewModel(@NonNull final Activity activity) {
256256
if (mViewModel != null && !mModelRemoved) {
257257
final ViewModelProvider viewModelProvider = getViewModelProvider(activity).getViewModelProvider();
258258
if (null == viewModelProvider) {

library/src/main/java/eu/inloop/viewmodel/base/ViewModelBaseActivity.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,8 @@ public R getViewModel() {
7070
return mViewModeHelper.getViewModel();
7171
}
7272

73+
@Override
74+
public void removeViewModel() {
75+
mViewModeHelper.removeViewModel(this);
76+
}
7377
}

library/src/main/java/eu/inloop/viewmodel/base/ViewModelBaseFragment.java

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,47 +15,47 @@
1515
public abstract class ViewModelBaseFragment<T extends IView, R extends AbstractViewModel<T>> extends Fragment implements IView {
1616

1717
@NonNull
18-
private final ViewModelHelper<T, R> mViewModeHelper = new ViewModelHelper<>();
18+
private final ViewModelHelper<T, R> mViewModelHelper = new ViewModelHelper<>();
1919

2020
@CallSuper
2121
@Override
2222
public void onCreate(@Nullable final Bundle savedInstanceState) {
2323
super.onCreate(savedInstanceState);
24-
getViewModeHelper().onCreate(getActivity(), savedInstanceState, getViewModelClass(), getArguments());
24+
getViewModelHelper().onCreate(getActivity(), savedInstanceState, getViewModelClass(), getArguments());
2525
}
2626

2727
@CallSuper
2828
@Override
2929
public void onSaveInstanceState(@NonNull final Bundle outState) {
3030
super.onSaveInstanceState(outState);
31-
getViewModeHelper().onSaveInstanceState(outState);
31+
getViewModelHelper().onSaveInstanceState(outState);
3232
}
3333

3434
@CallSuper
3535
@Override
3636
public void onStart() {
3737
super.onStart();
38-
getViewModeHelper().onStart();
38+
getViewModelHelper().onStart();
3939
}
4040

4141
@CallSuper
4242
@Override
4343
public void onStop() {
4444
super.onStop();
45-
getViewModeHelper().onStop();
45+
getViewModelHelper().onStop();
4646
}
4747

4848
@CallSuper
4949
@Override
5050
public void onDestroyView() {
51-
getViewModeHelper().onDestroyView(this);
51+
getViewModelHelper().onDestroyView(this);
5252
super.onDestroyView();
5353
}
5454

5555
@CallSuper
5656
@Override
5757
public void onDestroy() {
58-
getViewModeHelper().onDestroy(this);
58+
getViewModelHelper().onDestroy(this);
5959
super.onDestroy();
6060
}
6161

@@ -68,7 +68,7 @@ public void onDestroy() {
6868
@NonNull
6969
@SuppressWarnings("unused")
7070
public R getViewModel() {
71-
return getViewModeHelper().getViewModel();
71+
return getViewModelHelper().getViewModel();
7272
}
7373

7474
@Nullable
@@ -78,8 +78,13 @@ public ViewModelBindingConfig getViewModelBindingConfig() {
7878
}
7979

8080
@NonNull
81-
public ViewModelHelper<T, R> getViewModeHelper() {
82-
return mViewModeHelper;
81+
public ViewModelHelper<T, R> getViewModelHelper() {
82+
return mViewModelHelper;
83+
}
84+
85+
@Override
86+
public void removeViewModel() {
87+
mViewModelHelper.removeViewModel(getActivity());
8388
}
8489

8590
/**
@@ -89,6 +94,6 @@ public ViewModelHelper<T, R> getViewModeHelper() {
8994
* @param view view
9095
*/
9196
protected void setModelView(@NonNull final T view) {
92-
getViewModeHelper().setView(view);
97+
getViewModelHelper().setView(view);
9398
}
9499
}

library/src/main/java/eu/inloop/viewmodel/binding/ViewModelBaseBindingFragment.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ public abstract class ViewModelBaseBindingFragment<T extends IView, R extends Ab
2020
@Override
2121
public void onCreate(@Nullable Bundle savedInstanceState) {
2222
super.onCreate(savedInstanceState);
23-
getViewModeHelper().performBinding(this);
23+
getViewModelHelper().performBinding(this);
2424
}
2525

2626
@Nullable
2727
@Override
2828
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
29-
getViewModeHelper().performBinding(this);
30-
final ViewDataBinding binding = getViewModeHelper().getBinding();
29+
getViewModelHelper().performBinding(this);
30+
final ViewDataBinding binding = getViewModelHelper().getBinding();
3131
if (binding != null) {
3232
return binding.getRoot();
3333
} else {
@@ -39,7 +39,7 @@ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
3939
@NotNull
4040
public B getBinding() {
4141
try {
42-
return (B) getViewModeHelper().getBinding();
42+
return (B) getViewModelHelper().getBinding();
4343
} catch (ClassCastException ex) {
4444
throw new IllegalStateException("Method getViewModelBindingConfig() has to return same " +
4545
"ViewDataBinding type as it is set to base Fragment");
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package eu.inloop.viewmodel.support;
2+
3+
import android.app.Activity;
4+
import android.support.annotation.NonNull;
5+
import android.support.v4.app.Fragment;
6+
import android.support.v4.app.FragmentManager;
7+
import android.support.v4.app.FragmentStatePagerAdapter;
8+
import android.util.Log;
9+
import android.view.ViewGroup;
10+
11+
import eu.inloop.viewmodel.BuildConfig;
12+
import eu.inloop.viewmodel.IView;
13+
14+
/**
15+
* This class extends {@link FragmentStatePagerAdapter}. It removes the ViewModel once the
16+
* pager item is destroyed ({@link #destroyItem(ViewGroup, int, Object)}). The ViewModel state
17+
* is stored and then restored once you return back to this pager item and {@link #instantiateItem(ViewGroup, int)}
18+
* is called.
19+
*/
20+
public abstract class ViewModelStatePagerAdapter extends FragmentStatePagerAdapter {
21+
22+
public ViewModelStatePagerAdapter(@NonNull final FragmentManager fm) {
23+
super(fm);
24+
}
25+
26+
@Override
27+
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
28+
super.destroyItem(container, position, object);
29+
final Fragment fragment = (Fragment) object;
30+
31+
if (fragment instanceof IView) {
32+
IView viewModelBaseFragment = (IView) fragment;
33+
viewModelBaseFragment.removeViewModel();
34+
} else {
35+
if (BuildConfig.DEBUG) {
36+
Log.w("model", "Fragment " + fragment + " in FragmentStatePagerAdapter " + this + " doesn't implent IView"); //NON-NLS
37+
}
38+
}
39+
}
40+
}

sample/src/main/java/eu/inloop/viewmodel/sample/activity/ViewPagerActivity.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@
33
import android.os.Bundle;
44
import android.support.v4.app.Fragment;
55
import android.support.v4.app.FragmentManager;
6-
import android.support.v4.app.FragmentStatePagerAdapter;
76
import android.support.v4.view.ViewPager;
87

9-
import eu.inloop.viewmodel.base.ViewModelBaseActivity;
108
import eu.inloop.viewmodel.base.ViewModelBaseEmptyActivity;
119
import eu.inloop.viewmodel.sample.R;
1210
import eu.inloop.viewmodel.sample.fragment.PagerFragment;
11+
import eu.inloop.viewmodel.support.ViewModelStatePagerAdapter;
1312

1413
public class ViewPagerActivity extends ViewModelBaseEmptyActivity {
1514

@@ -22,7 +21,7 @@ protected void onCreate(Bundle savedInstanceState) {
2221
viewPager.setAdapter(new TestPagerAdapter(getSupportFragmentManager()));
2322
}
2423

25-
private final static class TestPagerAdapter extends FragmentStatePagerAdapter {
24+
private final static class TestPagerAdapter extends ViewModelStatePagerAdapter {
2625
public TestPagerAdapter(FragmentManager fm) {
2726
super(fm);
2827
}

0 commit comments

Comments
 (0)