Last active
June 14, 2018 03:46
-
-
Save vestrel00/982d585144423f728342787341fa001d to your computer and use it in GitHub Desktop.
B: 2 - Butterknife binding in onViewCreated vs onViewStateRestored
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Logs lifecycle events and provides subclasses a method to bind the views, bindViews(). | |
* | |
* Note that the bindViews() uses Butterknife to bind the views. However, the views | |
* can also be bound without using Butterknife. Using Butterknife or not | |
* plays no part in this demonstration. | |
*/ | |
// BaseFragment.java | |
public abstract class BaseFragment extends Fragment { | |
private static final String TAG = MainFragment.class.getSimpleName(); | |
private Unbinder unbinder; | |
@Override | |
public void onAttach(Context context) { | |
super.onAttach(context); | |
Log.d(TAG, "onAttach"); | |
} | |
@Override | |
public void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
Log.d(TAG, "onCreate - savedInstanceState is null? " + (savedInstanceState == null)); | |
} | |
@Override | |
public View onCreateView(LayoutInflater inflater, ViewGroup container, | |
Bundle savedInstanceState) { | |
Log.d(TAG, "onCreateView - savedInstanceState is null? " + (savedInstanceState == null)); | |
return inflater.inflate(R.layout.fragment_main, container, false); | |
} | |
@Override | |
public void onViewCreated(View view, Bundle savedInstanceState) { | |
super.onViewCreated(view, savedInstanceState); | |
Log.d(TAG, "onViewCreated - savedInstanceState is null? " + (savedInstanceState == null)); | |
} | |
@Override | |
public void onActivityCreated(Bundle savedInstanceState) { | |
super.onActivityCreated(savedInstanceState); | |
Log.d(TAG, "onActivityCreated - savedInstanceState is null? " + (savedInstanceState == null)); | |
} | |
@Override | |
public void onViewStateRestored(Bundle savedInstanceState) { | |
super.onViewStateRestored(savedInstanceState); | |
Log.d(TAG, "onViewStateRestored - savedInstanceState is null? " + (savedInstanceState == null)); | |
} | |
@Override | |
public void onResume() { | |
super.onResume(); | |
Log.d(TAG, "onResume"); | |
} | |
@Override | |
public void onDestroyView() { | |
super.onDestroyView(); | |
unbinder.unbind(); | |
} | |
@OnCheckedChanged(R.id.checkedTextView) | |
void onCheckBoxCheckedChanged(boolean checked) { | |
Log.d(TAG, "onCheckBoxCheckedChanged - " + checked); | |
if (checked) { | |
doSomethingWhenChecked(); | |
} | |
} | |
protected void bindViews() { | |
unbinder = ButterKnife.bind(this, getView()); | |
} | |
private void doSomethingWhenChecked() { | |
Log.d(TAG, "Maybe do a background operation that updates some user data locally or over the network"); | |
// Maybe bind views with data. | |
// Maybe do magic! | |
} | |
} | |
/** | |
* The following lifecycle events occur after checking the checkBox and rotating the device, | |
* which triggers Fragment recreation. | |
* | |
* D: onAttach | |
* D: onCreate - savedInstanceState is null? false | |
* D: onCreateView - savedInstanceState is null? false | |
* D: onViewCreated - savedInstanceState is null? false | |
* D: onActivityCreated - savedInstanceState is null? false | |
* D: onCheckBoxCheckedChanged - true | |
* D: Maybe do a background operation that updates some user data locally or over the network | |
* D: onViewStateRestored - savedInstanceState is null? false | |
* D: onResume | |
* | |
* Notice that onCheckBoxCheckedChanged is triggered during the (re)creation of the Fragment | |
* because Android itself saves and restores the states of views. | |
* | |
* This may produce unwanted side-effects; such as performing a background | |
* operation that updates some user data locally or over the network would be triggered | |
* without direct user action. In other words, a piece of code will get implicitly triggered | |
* during recreation, which is something that we may not want. | |
* | |
* You may use this side-effect to your advantage in your own project if so desired. | |
* However, do be aware of this side-effect as it is not limited to CheckedChanged events. | |
* This is also the case for SeekBarChange events, RatingBarChange events, and TextChanged events. | |
*/ | |
// BindViewsInOnViewCreatedFragment.java | |
public final class BindViewsInOnViewCreatedFragment extends BaseFragment { | |
@Override | |
public void onViewCreated(View view, Bundle savedInstanceState) { | |
super.onViewCreated(view, savedInstanceState); | |
bindViews(); | |
} | |
} | |
/** | |
* The following lifecycle events occur after checking the checkBox and rotating the device, | |
* which triggers Fragment recreation. | |
* | |
* D: onAttach | |
* D: onCreate - savedInstanceState is null? false | |
* D: onCreateView - savedInstanceState is null? false | |
* D: onViewCreated - savedInstanceState is null? false | |
* D: onActivityCreated - savedInstanceState is null? false | |
* D: onViewStateRestored - savedInstanceState is null? false | |
* D: onResume | |
* | |
* Notice that onCheckBoxCheckedChanged is NOT triggered during the (re)creation of the Fragment | |
* because the OS has finished restoring the state of views at this point. | |
* | |
* This means that CheckedChanged events (among other similar events), will not trigger unless | |
* explicitly triggered (usually by the user). This is the desired behavior in all of the projects | |
* I have worked on so far. | |
*/ | |
// BindViewsInOnViewStateRestoredFragment.java | |
public final class BindViewsInOnViewStateRestoredFragment extends BaseFragment { | |
@Override | |
public void onViewStateRestored(Bundle savedInstanceState) { | |
super.onViewStateRestored(savedInstanceState); | |
bindViews(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment