简体   繁体   中英

life cycle callbacks of fragments are not called accordingly

I have a main activity with view pager and three action tabs "fragment". and i implemented the life cycle callbacks for each of the main activity and the three fragments. and in each of the life cycle call back i placed a log statements indicates which life cycle callback being called to know how the action bars with view pager behaves. at run time i perceived a strange behaviour which i cant understand or attribute it to any reason.

first behaviour

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()

and i cant find any reason why only the life cycle callbacks of the mainactivty, frag_1 and frag_2 were called BUT NOT frag_3? any explaination?

2nd behaviour

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()

i think being the life cycle callbackes were called this is understandable, but why ONLY the life cycle callbacks of frag_1 also called, i think, beside the callbacks of frag_3 and frag_1, aslo frag_2 callbacks must have been called because frag_2 was in its onResume() state lately.

any explaination?

mainactivity

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()");
}

}

In the ViewPager, fragments are being created ahead of time.

That means, that your Frag_2 is not visible yet (because Frag_1 covers the entire screen), but it still creates the view beforehand, so scrolling to Frag_2 will be smooth.

By default, the ViewPager preloads one fragment on each side. So if you would set the start position of the ViewPager to Frag_2 , it would load Frag_1 and Frag_2 as well, because they are the neighbors.

You'll notice that Frag_3 will be created when you swipe to Frag_2

You can increase the number of preloaded fragments by calling ViewPager.setOffscreenPageLimit(int limit) .

Note that the min. number is 1, so this can not be disabled.

The life cycle callbacks are ok..

Check the setOffscreenPageLimit method, you can use it to Set the number of pages that should be retained to either side of the current page in the view hierarchy in an idle state. By default it set 1, thats the reason because your have that behaviour..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM