Skip to content

Instantly share code, notes, and snippets.

@vestrel00
Last active June 14, 2018 03:46
Show Gist options
  • Save vestrel00/982d585144423f728342787341fa001d to your computer and use it in GitHub Desktop.
Save vestrel00/982d585144423f728342787341fa001d to your computer and use it in GitHub Desktop.
B: 2 - Butterknife binding in onViewCreated vs onViewStateRestored
/**
* 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