Android Fragments 查看寻呼机和片段生命周期

rm5edbpk  于 2022-11-24  发布在  Android
关注(0)|答案(8)|浏览(172)

我有一个ViewPager,一次加载三个页面。如果我从第1页滑动到第2页,然后滑动到第3页,第一页(片段)会转到onPause()。然后,如果我滑动到第二页,第一页会转到onResume(),即使用户仍然看不到第一页。所以,我的问题是:如何区分代码中的第一页和第二页?2例如,如果我必须在代码片段可见时运行一段代码,这是如何做到的?

up9lanfz

up9lanfz1#

FragmentPagerAdapter将显示的片段之外的其他片段保持在恢复状态。解决方案是实现一个自定义的OnPageChangeListener,并创建一个新的方法用于显示片段。
1)创建LifecycleManager接口该接口将有两个方法,每个ViewPager的Fragment都将实现它。

public interface FragmentLifecycle {

    public void onPauseFragment();
    public void onResumeFragment();

}

2)让每个Fragment为每个类声明实现接口Add iplements语句:

public class FragmentBlue extends Fragment implements FragmentLifecycle
public class FragmentGreen extends Fragment implements FragmentLifecycle
public class FragmentPink extends Fragment implements FragmentLifecycle

3)在每个片段中实现接口方法为了检查它是否真的如预期的那样工作,我将只记录方法调用并显示吐司:

@Override
public void onPauseFragment() {
    Log.i(TAG, "onPauseFragment()");
    Toast.makeText(getActivity(), "onPauseFragment():" + TAG, Toast.LENGTH_SHORT).show(); 
}

@Override
public void onResumeFragment() {
    Log.i(TAG, "onResumeFragment()");
    Toast.makeText(getActivity(), "onResumeFragment():" + TAG, Toast.LENGTH_SHORT).show(); 
}

4)在ViewPager页面更改上调用接口方法您可以在ViewPager上设置OnPageChangeListener,并在ViewPager每次显示另一个页面时获得回调:

pager.setOnPageChangeListener(pageChangeListener);

5)实现OnPageChangeListener以调用自定义生命周期方法
侦听器知道新的位置,并可以在PagerAdapter的帮助下调用新片段上的接口方法。我可以在这里为新片段调用onResumeFragment(),并为当前片段调用onPauseFragment()。
我还需要存储当前片段的位置(最初的当前位置等于0),因为我不知道用户是从左到右滚动还是从右到左滚动。

private OnPageChangeListener pageChangeListener = new OnPageChangeListener() {

    int currentPosition = 0;

    @Override
    public void onPageSelected(int newPosition) {

        FragmentLifecycle fragmentToShow = (FragmentLifecycle)pageAdapter.getItem(newPosition);
        fragmentToShow.onResumeFragment();

        FragmentLifecycle fragmentToHide = (FragmentLifecycle)pageAdapter.getItem(currentPosition);
        fragmentToHide.onPauseFragment();

        currentPosition = newPosition;
    }

    @Override
    public void onPageScrolled(int arg0, float arg1, int arg2) { }

    public void onPageScrollStateChanged(int arg0) { }
};

我没有写代码。完整的教程在这里:http://looksok.wordpress.com/2013/11/02/viewpager-with-detailed-fragment-lifecycle-onresumefragment-including-source-code/

kcwpcxri

kcwpcxri2#

如果您的片段扩展了android.support.v4.app.Fragment
你可以用这个,我用得上

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (!isVisibleToUser) {
        //do sth..
    }
}
lnvxswe2

lnvxswe23#

使用者方法pager.setOffscreenPageLimit(numbr)来设定您要在堆栈中保留多少个片段。

qyyhg6bp

qyyhg6bp4#

覆写setUserVisibleHint()。这个方法会在片段对使用者可见时呼叫。

jchrr9hc

jchrr9hc5#

Override**setUserVisibleHint()**当片段对用户可见时将调用

fae0ux8s

fae0ux8s6#

解决您的问题:

public class FragmentVisibleHelper implements LifecycleObserver {

    private static final String TAG = "VipVisibleHelper";

    public interface IVisibleListener {

        void onVisible();

        void onInVisible();
    }

    boolean mIsVisibleToUser;
    boolean mStarted = false;

    volatile boolean mIsCalledVisible = false;
    volatile boolean mIsCalledInvisible = false;

    IVisibleListener mListener;

    public void setListener(IVisibleListener mListener) {
        this.mListener = mListener;
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    void onResume() {
        Log.d(TAG, String.format("%-60s %s", this.toString(), "onResume() called:"));
        if (mIsVisibleToUser) {
            dispatchVisible();
        }
    }

    private void dispatchVisible() {
        Log.d(TAG, String.format("%-60s %s", this.toString(), "dispatchVisible() called mIsCalledVisible = [" + mIsCalledVisible + "] mIsCalledInvisible = [" + mIsCalledInvisible + "] "));
        if (!mIsCalledVisible) {
            mIsCalledVisible = true;
            mIsCalledInvisible = false;

            if (Profile.LOG) {
                Log.d(TAG, String.format("%-60s %s", this.toString(), "dispatchVisible() called onVisible"));
            }

            if (mListener != null) {
                mListener.onVisible();
            }
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    void onPause() {
        Log.d(TAG, String.format("%-60s %s", this.toString(), "onPause() called:"));
        if (mIsVisibleToUser) {
            dispatchInvisible();
        }
    }

    private void dispatchInvisible() {
        Log.d(TAG, String.format("%-60s %s", this.toString(), "dispatchInvisible() called mIsCalledVisible = [" + mIsCalledVisible + "] mIsCalledInvisible = [" + mIsCalledInvisible + "] "));
        if (!mIsCalledInvisible) {
            mIsCalledInvisible = true;
            mIsCalledVisible = false;

            if (Profile.LOG) {
                Log.d(TAG, String.format("%-60s %s", this.toString(), "dispatchInvisible() called onInVisible"));
            }

            if (mListener != null) {
                mListener.onInVisible();
            }
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    void onStart() {
        Log.d(TAG, String.format("%-60s %s", this.toString(), "onStart() called"));
        mStarted = true;
        if (mIsVisibleToUser) {
            dispatchVisible();
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    void onStop() {
        Log.d(TAG, String.format("%-60s %s", this.toString(), "onStop() called"));
        if (mIsVisibleToUser) {
            dispatchInvisible();
        }
        mStarted = false;
    }

    public void setUserVisibleHint(boolean isVisibleToUser) {
        Log.d(TAG, String.format("%-60s %s", this.toString(), "setUserVisibleHint() called with: isVisibleToUser = [" + isVisibleToUser + "]:"));
        mIsVisibleToUser = isVisibleToUser;
        if (mStarted) { // fragment have created
            if (mIsVisibleToUser) {
                dispatchVisible();
            } else {
                dispatchInvisible();
            }
        }
    }

    public boolean isVisibleToUser() {
        return mIsVisibleToUser;
    }
}
jpfvwuh4

jpfvwuh47#

在片段之间滑动时,不会调用片段的生命周期方法。您可以使用ViewPager.SimpleOnPageChangeListener来解决这个问题。示例代码如下(在Kotlin中)。

// other code
mViewPager.addOnPageChangeListener(object: ViewPager.SimpleOnPageChangeListener() {
    override fun onPageSelected(position: Int) {
        val oldPosition = mViewPager.currentItem
        val oldFragment = mViewPager.adapter?.instantiateItem(mViewPager, oldPosition)
        oldFragment.onPauseStuff() // Hint: do as here call onPause
        val newFragment = mViewPager.adapter?.instantiateItem(mViewPager, position)
        newFragment.onResumeStuff() // Hint: do as here call onResume
}
// other code
xqk2d5yq

xqk2d5yq8#

您可以将此方法放在寻呼适配器内。

public Object instantiateItem(@NonNull ViewGroup container, int position) {
        Fragment fragment = fragments.get(position);
        if (fragment == null) {
            fragment = (Fragment) super.instantiateItem(container, position);
            fragments.put(position, fragment);
        }
        return fragment;
    }

    public Fragment getFragment(int position) {
        return fragments.get(position);
    }

然后,在页面更改侦听器中,您可以获取当前片段,并在片段中运行方法。

currentFragment = adapter.getFragment(viewPager.getCurrentItem());
((DetailNewsFragment)currentFragment).runYourMethod();

特殊不要使用adapter.getItem(position).,因为它返回一个片段的新示例。

相关问题