public abstract class BaseLazyFragment extends BaseFragment { private boolean isFragmentVisible; private boolean isFirstVisible = true; private View rootView; @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { //如果setUserVisibleHint()在rootView创建前调用时,那么 //就等到rootView创建完后才回调onFragmentVisibleChange(true) //保证onFragmentVisibleChange()的回调发生在rootView创建完成之后,以便支持ui操作 if (rootView == null) { rootView = view; if (getUserVisibleHint()) { if (isFirstVisible) { onLoadData(); isFirstVisible = false; } onFragmentVisibleChange(true); isFragmentVisible = true; } } super.onViewCreated(rootView, savedInstanceState); } @Override public void onDestroy() { super.onDestroy(); initVariable(); } private void initVariable() { isFirstVisible = true; isFragmentVisible = false; rootView = null; } /** * 去除setUserVisibleHint()多余的回调场景,保证只有当fragment可见状态发生变化时才回调 * 回调时机在view创建完后,所以支持ui操作,解决在setUserVisibleHint()里进行ui操作有可能报null异常的问题 * <p> * 可在该回调方法里进行一些ui显示与隐藏,比如加载框的显示和隐藏 * * @param isVisible true 不可见 -> 可见 * false 可见 -> 不可见 */ protected void onFragmentVisibleChange(boolean isVisible) { } /** * 在fragment首次可见时回调,可在这里进行加载数据,保证只在第一次打开Fragment时才会加载数据, * 这样就可以防止每次进入都重复加载数据 * 该方法会在 onFragmentVisibleChange() 之前调用,所以第一次打开时,可以用一个全局变量表示数据下载状态, * 然后在该方法内将状态设置为下载状态,接着去执行下载的任务 * 最后在 onFragmentVisibleChange() 里根据数据下载状态来控制下载进度ui控件的显示与隐藏 */ protected void onLoadData() { } public boolean isFragmentVisible() { return isFragmentVisible; } /** * setUserVisibleHint()在Fragment创建时会先被调用一次,传入isVisibleToUser = false * 如果当前Fragment可见,那么setUserVisibleHint()会再次被调用一次,传入isVisibleToUser = true * 如果Fragment从可见->不可见,那么setUserVisibleHint()也会被调用,传入isVisibleToUser = false * 总结:setUserVisibleHint()除了Fragment的可见状态发生变化时会被回调外,在new Fragment()时也会被回调 * 如果我们需要在 Fragment 可见与不可见时干点事,用这个的话就会有多余的回调了,那么就需要重新封装一个 * * @param isVisibleToUser */ @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); //setUserVisibleHint()有可能在fragment的生命周期外被调用 if (rootView == null) { return; } if (isFirstVisible && isVisibleToUser) { onLoadData(); isFirstVisible = false; } if (isVisibleToUser) { onFragmentVisibleChange(true); isFragmentVisible = true; return; } if (isFragmentVisible) { isFragmentVisible = false; onFragmentVisibleChange(false); } } }
/**
* Called immediately after {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}
* has returned, but before any saved state has been restored in to the view.
* This gives subclasses a chance to initialize themselves once
* they know their view hierarchy has been completely created. The fragment's
* view hierarchy is not however attached to its parent at this point.
* @param view The View returned by {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}.
* @param savedInstanceState If non-null, this fragment is being re-constructed
* from a previous saved state as given here.
*/
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
}
onViewCreated(View view, @Nullable Bundle savedInstanceState) 在onCreateView(LayoutInflater, ViewGroup, Bundle) 之后调用