片段的生命周期回调没有被相应地调用

life cycle callbacks of fragments are not called accordingly

我有一个主 activity,带有视图寻呼机和三个操作选项卡 "fragment"。我为每个主要 activity 和 三个片段。在每个生命周期回调中,我放置了一个日志语句,指示调用哪个生命周期回调以了解如何 带有视图寻呼机的操作栏行为。在 运行 的时候,我发现了一种我无法理解或归因于任何原因的奇怪行为。

第一次行为

when the App fisrt starts I receive:

02-08 15:16:14.771 32243-32243/com.example.com.vpager_00 W/MainActivity: onCreate()
02-08 15:16:14.901 32243-32243/com.example.com.vpager_00 W/MainActivity: onStart()
02-08 15:16:14.901 32243-32243/com.example.com.vpager_00 W/MainActivity: onResume()
02-08 15:16:14.941 32243-32243/com.example.com.vpager_00 W/Frag_1: onAttach()
02-08 15:16:14.941 32243-32243/com.example.com.vpager_00 W/Frag_1: onCreate()
02-08 15:16:14.941 32243-32243/com.example.com.vpager_00 W/Frag_1: onCreateView()
02-08 15:16:14.941 32243-32243/com.example.com.vpager_00 W/Frag_1: onStart()
02-08 15:16:14.941 32243-32243/com.example.com.vpager_00 W/Frag_1: onResume()
02-08 15:16:14.941 32243-32243/com.example.com.vpager_00 W/Frag_2: onAttach()
02-08 15:16:14.941 32243-32243/com.example.com.vpager_00 W/Frag_2: onCreate()
02-08 15:16:14.941 32243-32243/com.example.com.vpager_00 W/Frag_2: onCreateView()
02-08 15:16:14.941 32243-32243/com.example.com.vpager_00 W/Frag_2: onStart()
02-08 15:16:14.941 32243-32243/com.example.com.vpager_00 W/Frag_2: onResume()

而且我找不到任何理由为什么只有 mainactivty、frag_1 和 frag_2 的生命周期回调被调用,而不是 frag_3?有什么解释吗?

第二行为

occured when i touched tab3 "frag_3", i received:

02-08 15:16:36.031 32243-32243/com.example.com.vpager_00 D/ViewRootImpl: ViewPostImeInputStage ACTION_DOWN
02-08 15:16:36.121 32243-32243/com.example.com.vpager_00 W/Frag_3: onAttach()
02-08 15:16:36.121 32243-32243/com.example.com.vpager_00 W/Frag_3: onCreate()
02-08 15:16:36.121 32243-32243/com.example.com.vpager_00 W/Frag_3: onCreateView()
02-08 15:16:36.121 32243-32243/com.example.com.vpager_00 W/Frag_3: onStart()
02-08 15:16:36.121 32243-32243/com.example.com.vpager_00 W/Frag_3: onResume()
02-08 15:16:36.461 32243-32243/com.example.com.vpager_00 W/Frag_1: onPause()
02-08 15:16:36.461 32243-32243/com.example.com.vpager_00 W/Frag_1: onStop()
02-08 15:16:36.471 32243-32243/com.example.com.vpager_00 W/Frag_1: onDestroy()

我认为调用生命周期回调是可以理解的,但我认为为什么只有 frag_1 的生命周期回调也被调用, 除了 frag_3 和 frag_1 的回调之外,还必须调用 frag_2 回调,因为 frag_2 最近处于 onResume() 状态。

有什么解释吗?

主要activity

public class MainActivity extends AppCompatActivity {

private final String TAG = this.getClass().getSimpleName();

private Toolbar mTB = null;
private TabLayout mTL = null;
private ViewPager mVP = null;
private VPagerAdapter mVPAdapter = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.w(TAG, "onCreate()");

    this.initViews(R.layout.act_main);
    this.initObjs();
}

private void initObjs() {
    this.mVPAdapter = new VPagerAdapter(getSupportFragmentManager(), this.mTL.getTabCount());
    this.mVP.setAdapter(this.mVPAdapter);

    this.mVP.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(this.mTL));
    this.mTL.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            mVP.setCurrentItem(tab.getPosition());
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });
}

private void initViews(int rootView) {
    setContentView(rootView);

    this.mTB = (Toolbar) findViewById(R.id.toolbar);
    this.mTL = (TabLayout) findViewById(R.id.tab_layout);
    this.mVP = (ViewPager) findViewById(R.id.pager);

    setSupportActionBar(this.mTB);
    this.mTL.addTab(this.mTL.newTab().setText("Tab 1"));
    this.mTL.addTab(this.mTL.newTab().setText("Tab 2"));
    this.mTL.addTab(this.mTL.newTab().setText("Tab 3"));
    this.mTL.setTabGravity(TabLayout.GRAVITY_FILL);
}

@Override
protected void onStart() {
    super.onStart();
    Log.w(TAG, "onStart()");
}

@Override
protected void onResume() {
    super.onResume();
    Log.w(TAG, "onResume()");
}

@Override
protected void onPause() {
    super.onPause();
    Log.w(TAG, "onPause()");
}

@Override
protected void onStop() {
    super.onStop();
    Log.w(TAG, "onStop()");
}

@Override
protected void onDestroy() {
    super.onDestroy();
    Log.w(TAG, "onDestroy()");
}

}

frag_1

public class Frag_1 extends Fragment {

private final String TAG = this.getClass().getSimpleName();

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    Log.w(TAG, "onAttach()");
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.w(TAG, "onCreate()");
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    Log.w(TAG, "onCreateView()");

    return inflater.inflate(R.layout.frag_1, container, false);
}

@Override
public void onStart() {
    super.onStart();
    Log.w(TAG, "onStart()");
}

@Override
public void onResume() {
    super.onResume();
    Log.w(TAG, "onResume()");
}

@Override
public void onPause() {
    super.onPause();
    Log.w(TAG, "onPause()");
}

@Override
public void onStop() {
    super.onStop();
    Log.w(TAG, "onStop()");
}

@Override
public void onDestroy() {
    super.onDestroy();
    Log.w(TAG, "onDestroy()");
}

}

frag_2:

public class Frag_2 extends Fragment {

private final String TAG = this.getClass().getSimpleName();

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    Log.w(TAG, "onAttach()");
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.w(TAG, "onCreate()");
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    Log.w(TAG, "onCreateView()");

    return inflater.inflate(R.layout.frag_2, container, false);
}

@Override
public void onStart() {
    super.onStart();
    Log.w(TAG, "onStart()");
}

@Override
public void onResume() {
    super.onResume();
    Log.w(TAG, "onResume()");
}

@Override
public void onPause() {
    super.onPause();
    Log.w(TAG, "onPause()");
}

@Override
public void onStop() {
    super.onStop();
    Log.w(TAG, "onStop()");
}

@Override
public void onDestroy() {
    super.onDestroy();
    Log.w(TAG, "onDestroy()");
}

}

frag_3:

public class Frag_3 extends Fragment {

private final String TAG = this.getClass().getSimpleName();

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    Log.w(TAG, "onAttach()");
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.w(TAG, "onCreate()");
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    Log.w(TAG, "onCreateView()");

    return inflater.inflate(R.layout.frag_3, container, false);
}

@Override
public void onStart() {
    super.onStart();
    Log.w(TAG, "onStart()");
}

@Override
public void onResume() {
    super.onResume();
    Log.w(TAG, "onResume()");
}

@Override
public void onPause() {
    super.onPause();
    Log.w(TAG, "onPause()");
}

@Override
public void onStop() {
    super.onStop();
    Log.w(TAG, "onStop()");
}

@Override
public void onDestroy() {
    super.onDestroy();
    Log.w(TAG, "onDestroy()");
}

}

在 ViewPager 中,正在提前创建片段。

这意味着,您的 Frag_2 尚不可见(因为 Frag_1 覆盖了整个屏幕),但它仍会预先创建视图,因此滚动到 Frag_2 将是顺利。

默认情况下,ViewPager 会在每一侧预加载一个片段。因此,如果您将 ViewPager 的起始位置设置为 Frag_2,它也会加载 Frag_1Frag_2,因为它们是邻居。

您会注意到当您滑动到 Frag_2

时会创建 Frag_3

您可以通过调用ViewPager.setOffscreenPageLimit(int limit)来增加预加载片段的数量。

请注意,最小值。 number 为 1,因此无法禁用。

生命周期回调正常..

选中setOffscreenPageLimit方法,你可以用它来设置在空闲状态下视图层次结构中当前页面的任一侧应该保留的页面数。默认情况下它设置为 1,这就是原因,因为你有这种行为..