我使用以下方法通过显示/隐藏它们来切换片段(在我的NavigationDrawer中)。
protected void showFragment(int container, Fragment fragment, String tag, String lastTag, boolean addToBackStack ) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
if ( lastTag != null && !lastTag.equals("")) {
Fragment lastFragment = fragmentManager.findFragmentByTag( lastTag );
if ( lastFragment != null ) {
transaction.hide( lastFragment );
}
}
if ( fragment.isAdded() ) {
transaction.show( fragment );
}
else {
transaction.add( container, fragment, tag );
}
if ( addToBackStack ) {
transaction.addToBackStack( tag );
}
transaction.commit();
// set the active tag
activeFragTag = tag;
}
我不清楚的是,当我显示或隐藏它时,会调用Fragments生命周期的哪个方法?(因为没有像onShow()或onHide()这样的方法我不太确定怎么用)。我希望在显示和隐藏某个片段时执行特定操作。
答案 0 :(得分:101)
与活动生命周期类似,当片段变为可见时,Android会调用onStart()。当片段变得不可见时,通常会调用onStop()
,但也可以在以后调用它。
根据您的布局,当您的片段尚未显示时,Android甚至可以调用onStart()
,但它属于可见的父容器。例如,这对于要求您覆盖Fragment.setUserVisibleHint()
方法的android.support.v4.view.ViewPager
有效。在任何情况下,如果您需要注册/取消注册BroadcastReceivers或其他侦听器,您可以安全地使用onStart()
和onStop()
方法,因为这些方法将始终被调用。
注意:某些片段容器可以保持不可见的片段启动。要处理这种情况,您可以覆盖Fragment.onHiddenChanged(boolean hidden)
。根据{{3}},片段必须已启动且可见(未隐藏),以便用户可见。
更新:如果您使用android.support.v4.widget.DrawerLayout
,则即使抽屉打开,抽屉下方的片段也会保持开启状态。在这种情况下,您需要使用DrawerLayout.setDrawerListener()
并收听onDrawerClosed()
和onDrawerOpened()
回调。
答案 1 :(得分:49)
我@Override这个方法并解决了我的问题:
@Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if (hidden) {
//do when hidden
} else {
//do when show
}
}
答案 2 :(得分:33)
当然,您可以按照以下方法@Overriede执行此操作:
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
// Do your Work
} else {
// Do your Work
}
}
答案 3 :(得分:3)
视图分页器中的片段行为与常规片段容器不同。
尝试以下代码:
boolean mIsVisibleToUser;
/**
* is visible to user
*/
public void show() {
//do when show
}
/**
* is invisible to user
*/
public void hide() {
//do when gone
}
@Override
public void onResume() {
super.onResume();
if (!mIsVisibleToUser && getUserVisibleHint()) {
mIsVisibleToUser = true;
show();
}
}
@Override
public void onPause() {
super.onPause();
if (mIsVisibleToUser && getUserVisibleHint()) {
mIsVisibleToUser = false;
hide();
}
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isResumed()) {
if (mIsVisibleToUser != isVisibleToUser) {
mIsVisibleToUser = isVisibleToUser;
if (isVisibleToUser) show();
else hide();
}
}
}
public boolean isVisibleToUser() {
return mIsVisibleToUser;
}
答案 4 :(得分:1)
只需在 setUserVisibleHint()
中尝试此操作即可@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if(isVisibleToUser && getView() != null){
isActive = true;
init();
}else if(isVisibleToUser && getView() == null){
isActive = false;
}else{
isActive = true;
}
}
在 onCreateView():
中创建此代码public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
if(!isActive){
init();
}
}
答案 5 :(得分:0)
setUserVisibleHint
之前 onCreateView
致电。并且您无法更新setUserVisibleHint中的任何View我使用
public void setMenuVisibility(final boolean visible)
可见性和onHiddenChanged()第一次没有调用。它在隐藏状态改变时调用。因为fragment is visible by default
。为了首次实现此方法,您必须调用mFragmentTransaction.hide(oldFragment)
然后才能使用
注意
如果您想使用setUserVisible提示并更新View Use this method
答案 6 :(得分:0)
当片段可见并且您在活动中使用viewpager时调用片段方法的另一种方法。
//首先创建一个接口
public interface ShowFragmentVisible{
public void showFragment();}
//之后,此接口在Fragment中实现,就像那样
public class MyFragment extends Fragment implements
ShowFragmentVisible {
@Override
public void showFragment() {
}
//现在进入你的Activity然后创建接口对象并在addOnViewpagerListener
时调用 ShowFragmentVisible showFragmentVisible;
@Override
public void onAttachFragment(Fragment fragment) {
super.onAttachFragment(fragment);
if (fragment instanceof ShowFragmentVisible) {
showFragmentVisible = (ShowFragmentVisible) fragment;
}
}
//your viewpager method
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
if (position==0){
showFragmentVisible.showFragment();
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
this is another alternative,but its work for me successfully
答案 7 :(得分:0)
当然,您可以覆盖setUserVisibleHint
或setMenuVisibility
,但是如果您需要访问Context
或Activity
,则它们在那里为空!
还有另一种方法onStart
总是有可用的上下文,但是在创建片段时它只会被调用一次,并且如果您开始在寻呼机中的片段之间移动,您会发现它不会被调用在第二种观点之后。
那...现在该怎么办?
解决方法非常简单,第一次访问时使用onStart
,以后的访问时使用setMenuVisibility
。
您的代码可能如下所示:
片段类:
public class MyFragmentClass{
private boolean isCurrentVisible = false;
...
@Override
public void onStart() {
super.onStart();
if (isCurrentVisible)
doSth();
}
@Override
public void setMenuVisibility(boolean menuVisible){
super.setMenuVisibility(menuVisible);
this.isCurrentVisible = menuVisible;
if(menuVisible && getContext() != null)
doSth();
}
通过这种方式Context
始终可用于doSth()
方法。
答案 8 :(得分:0)
您可以使用“ onCreateView”(或“ onActivityCreated”)和“ onHiddenChanged”。 首先使用“ onCreateView”,然后使用“ onHiddenChanged”。 交易控制不会调用'setMenuVisibility'。
@Override
public View OnCreateView() {
// fragment will show first
}
@Override
public void onHiddenChanged(boolean hidden) {
if (!hidden) {
// fragment will show
}
else {
// fragment will hide
}
}
答案 9 :(得分:0)
这只对我有用!!并且setUserVisibleHint(...)
现在已弃用(我在文档末尾附加了文档),这意味着其他一些答案也已弃用;-)
public class FragmentFirewall extends Fragment {
/**
* Required cause "setMenuVisibility(...)" is not guaranteed to be
* called after "onResume()" and/or "onCreateView(...)" method.
*/
protected void didVisibilityChange() {
Activity activity = getActivity();
if (isResumed() && isMenuVisible()) {
// Once resumed and menu is visible, at last
// our Fragment is really visible to user.
}
}
@Override
public void onResume() {
super.onResume();
didVisibilityChange();
}
@Override
public void setMenuVisibility(boolean visible) {
super.setMenuVisibility(visible);
didVisibilityChange();
}
}
经过测试,也可以与NaviagationDrawer
一起使用,
那里isMenuVisible()
总是会返回true
(而且onResume()
似乎足够,但我们也想支持ViewPager
)。
setUserVisibleHint
已过时。如果覆盖此方法,则应将传入true
时实现的行为移至Fragment.onResume()
,并将传入false
时实现的行为移至Fragment.onPause()
。