22
33import android .app .Activity ;
44import android .content .Intent ;
5+ import android .databinding .DataBindingUtil ;
6+ import android .databinding .ViewDataBinding ;
57import android .os .Bundle ;
68import android .support .annotation .NonNull ;
79import android .support .annotation .Nullable ;
810import android .support .v4 .app .Fragment ;
911import android .util .Log ;
12+ import android .view .LayoutInflater ;
1013
1114import java .util .UUID ;
1215
16+ import eu .inloop .viewmodel .binding .ViewModelBindingConfig ;
17+
1318public class ViewModelHelper <T extends IView , R extends AbstractViewModel <T >> {
1419
1520 @ NonNull
@@ -21,18 +26,22 @@ public class ViewModelHelper<T extends IView, R extends AbstractViewModel<T>> {
2126 @ Nullable
2227 private R mViewModel ;
2328
29+ @ Nullable
30+ private ViewDataBinding mBinding ;
31+
2432 private boolean mModelRemoved ;
2533 private boolean mOnSaveInstanceCalled ;
2634
2735 /**
2836 * Call from {@link android.app.Activity#onCreate(android.os.Bundle)} or
2937 * {@link android.support.v4.app.Fragment#onCreate(android.os.Bundle)}
30- * @param activity parent activity
38+ *
39+ * @param activity parent activity
3140 * @param savedInstanceState savedInstance state from {@link Activity#onCreate(Bundle)} or
3241 * {@link Fragment#onCreate(Bundle)}
33- * @param viewModelClass the {@link Class} of your ViewModel
34- * @param arguments pass {@link Fragment#getArguments()} or
35- * {@link Activity#getIntent()}.{@link Intent#getExtras() getExtras()}
42+ * @param viewModelClass the {@link Class} of your ViewModel
43+ * @param arguments pass {@link Fragment#getArguments()} or
44+ * {@link Activity#getIntent()}.{@link Intent#getExtras() getExtras()}
3645 */
3746 public void onCreate (@ NonNull Activity activity ,
3847 @ Nullable Bundle savedInstanceState ,
@@ -62,7 +71,7 @@ public void onCreate(@NonNull Activity activity,
6271 if (null == viewModelProvider ) {
6372 throw new IllegalStateException ("ViewModelProvider for activity " + activity + " was null." ); //NON-NLS
6473 }
65-
74+
6675 final ViewModelProvider .ViewModelWrapper <T > viewModelWrapper = viewModelProvider .getViewModel (mScreenId , viewModelClass );
6776 //noinspection unchecked
6877 mViewModel = (R ) viewModelWrapper .viewModel ;
@@ -79,6 +88,7 @@ public void onCreate(@NonNull Activity activity,
7988 /**
8089 * Call from {@link android.support.v4.app.Fragment#onViewCreated(android.view.View, android.os.Bundle)}
8190 * or {@link android.app.Activity#onCreate(android.os.Bundle)}
91+ *
8292 * @param view view
8393 */
8494 public void setView (@ NonNull final T view ) {
@@ -89,10 +99,44 @@ public void setView(@NonNull final T view) {
8999 mViewModel .onBindView (view );
90100 }
91101
102+ public void performBinding (@ NonNull final IView bindingView ) {
103+ // skip if already create
104+ if (mBinding != null ) {
105+ return ;
106+ }
107+
108+ // get ViewModelBinding config
109+ final ViewModelBindingConfig viewModelConfig = bindingView .getViewModelBindingConfig ();
110+ // if fragment not providing ViewModelBindingConfig, do not perform binding operations
111+ if (viewModelConfig == null ) {
112+ return ;
113+ }
114+
115+ // perform Data Binding initialization
116+ final ViewDataBinding viewDataBinding ;
117+ if (bindingView instanceof Activity ) {
118+ viewDataBinding = DataBindingUtil .setContentView (((Activity ) bindingView ), viewModelConfig .getLayoutResource ());
119+ } else if (bindingView instanceof Fragment ) {
120+ viewDataBinding = DataBindingUtil .inflate (LayoutInflater .from (viewModelConfig .getContext ()), viewModelConfig .getLayoutResource (), null , false );
121+ } else {
122+ throw new IllegalArgumentException ("View must be an instance of Activity or Fragment (support-v4)." );
123+ }
124+
125+ // bind all together
126+ if (!viewDataBinding .setVariable (viewModelConfig .getViewModelVariableName (), getViewModel ())) {
127+ throw new IllegalArgumentException ("Binding variable wasn't set successfully. Probably viewModelVariableName of your " +
128+ "ViewModelBindingConfig of " + bindingView .getClass ().getSimpleName () + " doesn't match any variable in "
129+ + viewDataBinding .getClass ().getSimpleName ());
130+ }
131+
132+ mBinding = viewDataBinding ;
133+ }
134+
92135 /**
93136 * Use in case this model is associated with an {@link android.support.v4.app.Fragment}
94137 * Call from {@link android.support.v4.app.Fragment#onDestroyView()}. Use in case model is associated
95138 * with Fragment
139+ *
96140 * @param fragment fragment
97141 */
98142 public void onDestroyView (@ NonNull Fragment fragment ) {
@@ -104,11 +148,13 @@ public void onDestroyView(@NonNull Fragment fragment) {
104148 if (fragment .getActivity () != null && fragment .getActivity ().isFinishing ()) {
105149 removeViewModel (fragment .getActivity ());
106150 }
151+ mBinding = null ;
107152 }
108153
109154 /**
110155 * Use in case this model is associated with an {@link android.support.v4.app.Fragment}
111156 * Call from {@link android.support.v4.app.Fragment#onDestroy()}
157+ *
112158 * @param fragment fragment
113159 */
114160 public void onDestroy (@ NonNull final Fragment fragment ) {
@@ -126,11 +172,13 @@ public void onDestroy(@NonNull final Fragment fragment) {
126172 }
127173 removeViewModel (fragment .getActivity ());
128174 }
175+ mBinding = null ;
129176 }
130177
131178 /**
132179 * Use in case this model is associated with an {@link android.app.Activity}
133180 * Call from {@link android.app.Activity#onDestroy()}
181+ *
134182 * @param activity activity
135183 */
136184 public void onDestroy (@ NonNull final Activity activity ) {
@@ -142,6 +190,7 @@ public void onDestroy(@NonNull final Activity activity) {
142190 if (activity .isFinishing ()) {
143191 removeViewModel (activity );
144192 }
193+ mBinding = null ;
145194 }
146195
147196 /**
@@ -172,6 +221,7 @@ public void onStart() {
172221 * Throws an {@link IllegalStateException} in case the ViewModel is null. This can happen
173222 * if you call this method too soon - before {@link Activity#onCreate(Bundle)} or {@link Fragment#onCreate(Bundle)}
174223 * or this {@link ViewModelHelper} is not properly setup.
224+ *
175225 * @return {@link R}
176226 */
177227 @ NonNull
@@ -186,6 +236,7 @@ public R getViewModel() {
186236 * Call from {@link android.app.Activity#onSaveInstanceState(android.os.Bundle)}
187237 * or {@link android.support.v4.app.Fragment#onSaveInstanceState(android.os.Bundle)}.
188238 * This allows the model to save its state.
239+ *
189240 * @param bundle bundle
190241 */
191242 public void onSaveInstanceState (@ NonNull Bundle bundle ) {
@@ -196,6 +247,11 @@ public void onSaveInstanceState(@NonNull Bundle bundle) {
196247 }
197248 }
198249
250+ @ Nullable
251+ public ViewDataBinding getBinding () {
252+ return mBinding ;
253+ }
254+
199255 private void removeViewModel (@ NonNull final Activity activity ) {
200256 if (mViewModel != null && !mModelRemoved ) {
201257 final ViewModelProvider viewModelProvider = getViewModelProvider (activity ).getViewModelProvider ();
@@ -205,6 +261,7 @@ private void removeViewModel(@NonNull final Activity activity) {
205261 viewModelProvider .remove (mScreenId );
206262 mViewModel .onDestroy ();
207263 mModelRemoved = true ;
264+ mBinding = null ;
208265 }
209266 }
210267
0 commit comments