For reprint, please indicate the original source: https://juejin.cn/post/6844903522052341768, thank you.
background
We have encountered several problems in the development process recently, such as
- Page statistics
- Start and pause Banner rotation
- And other custom requirements
These can be easily achieved in an Activity, but if there is a Fragment in the page, it cannot be implemented as simply as an Activity. The following is an analysis of different ways to use fragments.
Various methods of use
1. Use it directly in the Activity
This is the simplest case, where the Activity is introduced using XML, or loaded dynamically using the FragmentManager addFragment or replaceFrament. In this case, the Fragment’s onResume and onPause methods can be used to determine whether it is visible or not. It is visible to the user between onResume and onPause.
@Override
public void onResume() {
super.onResume();
// TODO now it's visible to user } @Override public void onPause() { super.onPause(); // TODO now it's invisible to user
}
Copy the code
2. Use show and hide to display hidden fragments
FragmentManager also has showFragment and hideFragment in addition to addFragment and replaceFragment to display and hide fragments, which can improve the speed of page switching. It is a way to exchange space for time. However, the Fragment used in this way will not call onPause when it is hidden. Because it’s just not visible on the screen anymore, but there’s no Pause. At this point we need to listen for the onHiddenChanged method.
@Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if(! hidden) { // TODO now it's visible to user } else { // TODO now it's invisible to user
}
}
Copy the code
3. Fragment in ViewPager
Now many apps will do TAB page, and TAB page is basically through the Android built-in ViewPager implementation. ViewPager has a feature that when I slide to a Tab, it loads both the left and right tabs of that Tab. For example, if I switch from page 1 to page 2, the onResume of page 3 is called, but page 3 is not visible to the user. We need to listen for setUserVisibleHint to determine whether it is visible to the user.
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
// TODO now it's visible to user } else { // TODO now it's invisible to user
}
}
Copy the code
Attention!! Attention!! Attention!!
In the following operation cases:
- StartActivity Indicates the page
- Press the Home button to return to the Home screen
- Return from another page or home screen
- And so on and so forth
Once the user has done so, all of the methods listed above that use fragments in the same Activity will call onResume or onPause, regardless of whether they are displayed.
Such as:
Fragment A contains fragments A and B, respectively. Fragment A contains fragments A and B.
- Fragment A, B, A, and B execute onPause while onHiddenChanged and setUserVisibleHint are not executed when returning to the home screen or switching to A new page.
- Also, when returning to the Activity page, Fragment A, Fragment B, Fragment A, Fragment B all execute onResume. OnHiddenChanged and setUserVisibleHint are not executed.
Because of these problems, onHiddenChanged, setUserVisibleHint, onResume, and onPause are used to determine the result.
The following code
public abstract class BaseFrameFragment extends Fragment { public BaseFrameActivity activity; private boolean isFirstCreate; Private Boolean isVisibleToUser; Private Boolean isLastVisibleToUser; @override public void onAttach(Context Context) {super.onattach (Context); LogUtil.i("onAttach:" + getFragmentName());
FragmentActivity activity = getActivity();
if (activity instanceof BaseFrameActivity) {
this.activity = (BaseFrameActivity) activity;
} else {
throw new IllegalArgumentException("Activity must inherit BaseFrameActivity");
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
LogUtil.i("onCreateView:" + getFragmentName());
View layout_root = View.inflate(activity, getContentViewResourceId(), null);
initData(getArguments());
initView(layout_root);
loadData();
setListener();
isFirstCreate = true;
returnlayout_root; } /** * Check whether the Fragment is visible ** @param hidden Check whether the Fragment is hidden */ @override public void onHiddenChanged(boolean hidden) { super.onHiddenChanged(hidden); LogUtil.i("onHiddenChanged:" + getFragmentName() + ""+ hidden); isLastVisibleToUser = ! hidden; onVisibleToUser(isLastVisibleToUser);setChildVisibleToUser(isLastVisibleToUser); } /** * use ViewPager to check whether the Fragment is visible ** @param isVisibleToUser is visible */ @override public void OverridesetUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (activity == null) {
LogUtil.i("setUserVisibleHint:" + isVisibleToUser);
return;
}
LogUtil.i("setUserVisibleHint:" + getFragmentName() + "" + isVisibleToUser);
isLastVisibleToUser = isVisibleToUser;
onVisibleToUser(isLastVisibleToUser);
setChildVisibleToUser(isLastVisibleToUser); } /** * the Activity uses XML to introduce, This method is also called when the Fragment is visible during dynamic loading using the FragmentManager addFragment or replaceFragment method @Override public voidonResume() {
super.onResume();
LogUtil.i("onResume:"+ getFragmentName()); // the ParentFragment isLastVisibleToUser state created for the first time and displayed to the user (ViewPager) or returned to the original pageif ((isFirstCreate && getUserVisibleHint()) || (isLastVisibleToUser && getParentFragmentLastVisibleToUser())) {
onVisibleToUser(true); }} /** * in the Activity using XML to introduce, This method is also called */ @override if the Fragment is visible during dynamic loading using the FragmentManager addFragment or replaceFragment method public voidonPause() {
super.onPause();
LogUtil.i("onPause:" + getFragmentName());
if (isLastVisibleToUser) {
onVisibleToUser(false); }} /** * Get ParentFragment isLastVisibleToUser statetrue* * @)return ParentFragment isLastVisibleToUser
*/
private boolean getParentFragmentLastVisibleToUser() {
Fragment parentFragment = getParentFragment();
if(parentFragment ! = null) {if (parentFragment instanceof BaseFrameFragment) {
BaseFrameFragment frameFragment = (BaseFrameFragment) parentFragment;
returnframeFragment.isLastVisibleToUser; }}return true; } /** * Set the sub-fragment display state ** @param isVisibleToUser isVisibleToUser */ private voidsetChildVisibleToUser(boolean isVisibleToUser) {
List<Fragment> fragmentList = getChildFragmentManager().getFragments();
if(! BaseUtils.isEmptyList(fragmentList)) {for (Fragment fragment : fragmentList) {
if (fragment instanceof BaseFrameFragment) {
BaseFrameFragment frameFragment = (BaseFrameFragment) fragment;
if(frameFragment.isLastVisibleToUser) { frameFragment.onVisibleToUser(isVisibleToUser); } } } } } public abstract String getFragmentName(); /** * Get the root layout ResourceId ** @returnRoot layout ResourceId */ public Abstract Int getContentViewResourceId(); /** * Initialization data, including unpacking parameters passed from the activity, adapter initialization, collection initialization, etc. Public abstract void initData(Bundle arguments); /** @param layout_root Fragment View */ public abstract void initView(View layout_root); Public void loadData(); public void loadData(); public void loadData(); /** * set listener */ public abstract voidsetListener(); /** * The operation performed when the user is visible/invisible (similar to the Activity onResume/onPause methods) ** @param isVisibleToUser is visible to the user */ public void onVisibleToUser(boolean isVisibleToUser) {if (this.isVisibleToUser == isVisibleToUser) {
return;
}
LogUtil.i("onVisibleToUser:" + getFragmentName() + "" + isVisibleToUser);
this.isVisibleToUser = isVisibleToUser;
isFirstCreate = false;
if (isVisibleToUser) {
isLastVisibleToUser = true; }}}Copy the code
The specific use
public class A_TempFragment extends BaseFrameFragment {
@Override
public String getFragmentName() {
return getString(R.string.app_name);
}
@Override
public int getContentViewResourceId() {
return R.layout.activity_base;
}
@Override
public void initData(Bundle arguments) {
}
@Override
public void initView(View layout_root) {
ButterKnife.bind(this, layout_root);
}
@Override
public void loadData() {
}
@Override
public void setListener() {
}
@Override
public void onVisibleToUser(boolean isVisibleToUser) {
super.onVisibleToUser(isVisibleToUser);
if (isVisibleToUser) {
// TODO now it's visible to user } else { // TODO now it's invisible to user
}
}
}
Copy the code
ViewPager+Fragment is a Fragment embedded in your Activity
The resources
www.cnblogs.com/dongweiq/p/…