Last active
March 27, 2017 07:32
-
-
Save BCsl/c36397be39e0a3135924e0db69204a18 to your computer and use it in GitHub Desktop.
在内存重启的时候自动恢复可见状态的Fragment,避免重叠现象,懒加载的Fragment
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
public abstract class BaseFragment extends Fragment { | |
public static final String IS_SHOW = "is_show"; | |
protected View mRootView; | |
@Override | |
public void onCreate(@Nullable Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
if (BuildConfig.DEBUG) { | |
Log.d(getClass().getSimpleName(), "onCreate:"); | |
} | |
if (savedInstanceState != null && getFragmentManager() != null) { | |
boolean isShow = savedInstanceState.getBoolean(IS_SHOW, true); | |
FragmentTransaction ft = getFragmentManager().beginTransaction(); | |
if (BuildConfig.DEBUG) { | |
Log.d(this.getClass().getSimpleName(), "restore show:" + isShow); | |
} | |
if (!isShow) { | |
ft.hide(this); | |
} else { | |
ft.show(this); | |
} | |
ft.commit(); | |
//是否从内存重启恢复后,并隐藏自己,某些情况下,可能在某个生命周期执行时(如onResume),进行动画等只是在用户操作界面之前才执行的初始化操作,这时候可以根据这个值来判断是否进行这些操作 | |
setUserVisibleHint(isShow); | |
} | |
} | |
@Override | |
public void onSaveInstanceState(Bundle outState) { | |
super.onSaveInstanceState(outState); | |
outState.putBoolean(IS_SHOW, !isHidden()); | |
} | |
@Override | |
public void onHiddenChanged(boolean hidden) { | |
super.onHiddenChanged(hidden); | |
if (BuildConfig.DEBUG) { | |
Log.d(getClass().getSimpleName(), "onHiddenChanged" + hidden); | |
} | |
} | |
@Nullable | |
@Override | |
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { | |
if (BuildConfig.DEBUG) { | |
Log.d(getClass().getSimpleName(), "onCreateView"); | |
} | |
mRootView = onCreateContentView(inflater, container, savedInstanceState); | |
return mRootView; | |
} | |
@Override | |
public void onViewCreated(View view, Bundle savedInstanceState) { | |
super.onViewCreated(view, savedInstanceState); | |
if (BuildConfig.DEBUG) { | |
Log.v(getClass().getSimpleName(), "onViewCreated"); | |
} | |
initView(view, savedInstanceState); | |
initData(savedInstanceState); | |
} | |
@Override | |
public void onStart() { | |
super.onStart(); | |
if (BuildConfig.DEBUG) { | |
Log.d(getClass().getSimpleName(), "onStart"); | |
} | |
} | |
@Override | |
public void onResume() { | |
super.onResume(); | |
if (BuildConfig.DEBUG) { | |
Log.d(getClass().getSimpleName(), "onResume(),should do animation:" + getUserVisibleHint()); | |
} | |
} | |
@Override | |
public void onPause() { | |
super.onPause(); | |
if (BuildConfig.DEBUG) { | |
Log.d(getClass().getSimpleName(), "onPause"); | |
} | |
} | |
@Override | |
public void onStop() { | |
super.onStop(); | |
if (BuildConfig.DEBUG) { | |
Log.d(getClass().getSimpleName(), "onStop"); | |
} | |
} | |
@Override | |
public void onDestroyView() { | |
super.onDestroyView(); | |
if (BuildConfig.DEBUG) { | |
Log.d(getClass().getSimpleName(), "onDestroyView"); | |
} | |
} | |
@Override | |
public void onDestroy() { | |
super.onDestroy(); | |
if (BuildConfig.DEBUG) { | |
Log.d(getClass().getSimpleName(), "onDestroy"); | |
} | |
} | |
protected abstract View onCreateContentView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState); | |
protected abstract void initView(View root, Bundle savedInstanceState); | |
protected abstract void initData(Bundle savedInstanceState); | |
} |
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
/** | |
* <h1>懒加载Fragment</h1> 只有创建并显示的时候才会调用onCreateViewLazy方法<br> | |
* <br> | |
* <p> | |
* 懒加载的原理onCreateView的时候Fragment有可能没有显示出来。<br> | |
* 但是调用到setUserVisibleHint(boolean isVisibleToUser),isVisibleToUser = | |
* true的时候就说明有显示出来<br> | |
* 但是要考虑onCreateView和setUserVisibleHint的先后问题所以才有了下面的代码 | |
* <p> | |
* 注意:<br> | |
* 《1》原先的Fragment的回调方法名字后面要加个Lazy,比如Fragment的onCreateView方法, 就写成onCreateViewLazy <br> | |
* 《2》使用该LazyFragment会导致多一层布局深度 | |
* <p> | |
* LuckyJayce | |
*/ | |
public class LazyFragment extends BaseFragment { | |
private boolean isInit = false; | |
private Bundle savedInstanceState; | |
public static final String INTENT_BOOLEAN_LAZYLOAD = "intent_boolean_lazyLoad"; | |
private boolean isLazyLoad = true; | |
private FrameLayout layout; | |
@Deprecated | |
protected final void onCreateView(Bundle savedInstanceState) { | |
super.onCreateView(savedInstanceState); | |
this.savedInstanceState = savedInstanceState; | |
Bundle bundle = getArguments(); | |
if (bundle != null) { | |
isLazyLoad = bundle.getBoolean(INTENT_BOOLEAN_LAZYLOAD, isLazyLoad); | |
} | |
if (isLazyLoad) { | |
if (getUserVisibleHint() && !isInit) { | |
isInit = true; | |
onCreateViewLazy(savedInstanceState); | |
} else { | |
LayoutInflater layoutInflater = inflater; | |
if (layoutInflater == null) { | |
layoutInflater = LayoutInflater.from(getApplicationContext()); | |
} | |
layout = new FrameLayout(layoutInflater.getContext()); | |
View view = getPreviewLayout(layoutInflater, layout); | |
if (view != null) { | |
layout.addView(view); | |
} | |
layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); | |
super.setContentView(layout); | |
} | |
} else { | |
isInit = true; | |
onCreateViewLazy(savedInstanceState); | |
} | |
} | |
@Override | |
public void setUserVisibleHint(boolean isVisibleToUser) { | |
super.setUserVisibleHint(isVisibleToUser); | |
if (isVisibleToUser && !isInit && getContentView() != null) { | |
isInit = true; | |
onCreateViewLazy(savedInstanceState); | |
onResumeLazy(); | |
} | |
if (isInit && getContentView() != null) { | |
if (isVisibleToUser) { | |
isStart = true; | |
onFragmentStartLazy(); | |
} else { | |
isStart = false; | |
onFragmentStopLazy(); | |
} | |
} | |
} | |
protected View getPreviewLayout(LayoutInflater inflater, ViewGroup container) { | |
return null; | |
} | |
@Deprecated | |
@Override | |
public final void onStart() { | |
super.onStart(); | |
if (isInit && !isStart && getUserVisibleHint()) { | |
isStart = true; | |
onFragmentStartLazy(); | |
} | |
} | |
@Deprecated | |
@Override | |
public final void onStop() { | |
super.onStop(); | |
if (isInit && isStart && getUserVisibleHint()) { | |
isStart = false; | |
onFragmentStopLazy(); | |
} | |
} | |
private boolean isStart = false; | |
protected void onFragmentStartLazy() { | |
} | |
protected void onFragmentStopLazy() { | |
} | |
protected void onCreateViewLazy(Bundle savedInstanceState) { | |
} | |
protected void onResumeLazy() { | |
} | |
protected void onPauseLazy() { | |
} | |
protected void onDestroyViewLazy() { | |
} | |
@Override | |
public void setContentView(int layoutResID) { | |
if (isLazyLoad && getContentView() != null && getContentView().getParent() != null) { | |
layout.removeAllViews(); | |
View view = inflater.inflate(layoutResID, layout, false); | |
layout.addView(view); | |
} else { | |
super.setContentView(layoutResID); | |
} | |
} | |
@Override | |
public void setContentView(View view) { | |
if (isLazyLoad && getContentView() != null && getContentView().getParent() != null) { | |
layout.removeAllViews(); | |
layout.addView(view); | |
} else { | |
super.setContentView(view); | |
} | |
} | |
@Override | |
@Deprecated | |
public final void onResume() { | |
super.onResume(); | |
if (isInit) { | |
onResumeLazy(); | |
} | |
} | |
@Override | |
@Deprecated | |
public final void onPause() { | |
super.onPause(); | |
if (isInit) { | |
onPauseLazy(); | |
} | |
} | |
@Override | |
@Deprecated | |
public final void onDestroyView() { | |
super.onDestroyView(); | |
if (isInit) { | |
onDestroyViewLazy(); | |
} | |
isInit = false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment