FragmentPagerAdapter Fragment的生命周期

前言

最近换了新工作,一直写业务,写的过程中碰到了viewPager结合Fragment的使用的场景,但是发现自己对此时Fragment的生命周期理解并不到位,在此做一下记录。

代码和布局文件

ActivityForViewPager.java

package com.xol.viewpagerfragment;

import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;

/**
 * Created by wwzhang on 2019/1/24
 */
public class ActivityForViewPager extends AppCompatActivity {

    private ViewPager viewPager;
    private TabLayout tabLayout;
    private String tabs[] = {"A", "B", "C", "D", "E"};

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_for_viewpager);
        initView();
    }

    private void initView() {
        viewPager = (ViewPager) findViewById(R.id.vp_content);
        tabLayout = (TabLayout) findViewById(R.id.tab_layout);
        tabLayout.setupWithViewPager(viewPager);
        viewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager(), tabs));

    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    protected void onStop() {
        super.onStop();
    }

    @Override
    protected void onStart() {
        super.onStart();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    /**
     * fagment
     */
    public static class ViewPagerFragment extends Fragment {

        private static final String TAG = "ViewPagerFragment";
        private String tab;

        public static Fragment createFragment(Bundle bundle) {
            Fragment fragment = new ViewPagerFragment();
            fragment.setArguments(bundle);
            return fragment;
        }

        @Override
        public void onAttach(Context context) {
            tab = getArguments().getString("tab");
            super.onAttach(context);
        }

        @Override
        public void onActivityCreated(@Nullable Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            Log.d(TAG, "onActivityCreated: " + tab);
        }

        @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            Log.d(TAG, "onCreate: " + tab);
        }

        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            Log.d(TAG, "onCreateView: " + tab);
            TextView textView = new TextView(container.getContext());
            FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT);
            params.gravity = Gravity.CENTER;
            textView.setPadding(25, 25, 25, 25);
            textView.setGravity(Gravity.CENTER);
            textView.setLayoutParams(params);
            textView.setText(tab);
            return textView;
        }

        @Override
        public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
            Log.d(TAG, "onViewCreated: " + tab);
            super.onViewCreated(view, savedInstanceState);
        }

        @Override
        public void onStart() {
            Log.d(TAG, "onStart: " + tab);
            super.onStart();
        }

        @Override
        public void onResume() {
            Log.d(TAG, "onResume: " + tab);
            super.onResume();
        }


        @Override
        public void onPause() {
            Log.d(TAG, "onPause: " + tab);
            super.onPause();
        }

        @Override
        public void onStop() {
            Log.d(TAG, "onStop: " + tab);
            super.onStop();
        }

        @Override
        public void onDestroyView() {
            Log.d(TAG, "onDestroyView: " + tab);
            super.onDestroyView();
        }

        @Override
        public void onDestroy() {
            Log.d(TAG, "onDestroy: " + tab);
            super.onDestroy();
        }

        @Override
        public void onDetach() {
            Log.d(TAG, "onDetach: " + tab);
            super.onDetach();
        }
    }


    /**
     * 适配器
     */
    public static class ViewPagerAdapter extends FragmentPagerAdapter {

        private String[] tabs;

        public ViewPagerAdapter(FragmentManager fm, String[] tabs) {
            super(fm);
            this.tabs = tabs;
        }

        @Override
        public Fragment getItem(int position) {
            Bundle bundle = new Bundle();
            bundle.putString("tab", tabs[position]);
//            return null;

            return ViewPagerFragment.createFragment(bundle);
        }

        @Override
        public int getCount() {
            return tabs.length;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return tabs[position];
        }
    }


}

activity_for_viewpager.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:padding="16dp"
        android:id="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="ViewPager" />

    <android.support.design.widget.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <android.support.v4.view.ViewPager
        android:id="@+id/vp_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

运行结果

在这里插入图片描述

Fragment典型周期图

在这里插入图片描述

viewPager 从A滑倒B输出日志

01-24 14:10:37.001 1805-1805/com.xol.viewpagerfragment D/ViewPagerFragment: onCreate: A
01-24 14:10:37.002 1805-1805/com.xol.viewpagerfragment D/ViewPagerFragment: onCreate: B
    onCreateView: A
01-24 14:10:37.004 1805-1805/com.xol.viewpagerfragment D/ViewPagerFragment: onViewCreated: A
    onActivityCreated: A
01-24 14:10:37.005 1805-1805/com.xol.viewpagerfragment D/ViewPagerFragment: onStart: A
    onResume: A
    onCreateView: B
01-24 14:10:37.006 1805-1805/com.xol.viewpagerfragment D/ViewPagerFragment: onViewCreated: B
    onActivityCreated: B
01-24 14:10:37.008 1805-1805/com.xol.viewpagerfragment D/ViewPagerFragment: onStart: B
    onResume: B
//上面为第一次打开该Activity日志输出

01-24 14:10:40.036 1805-1805/com.xol.viewpagerfragment D/ViewPagerFragment: onCreate: C
01-24 14:10:40.038 1805-1805/com.xol.viewpagerfragment D/ViewPagerFragment: onCreateView: C
01-24 14:10:40.039 1805-1805/com.xol.viewpagerfragment D/ViewPagerFragment: onViewCreated: C
    onActivityCreated: C
    onStart: C
    onResume: C
    
// 上面为viewPager滑动到B Fragment的日志输出
01-24 14:10:40.812 1805-1805/com.xol.viewpagerfragment D/ViewPagerFragment: onCreate: D
01-24 14:10:40.813 1805-1805/com.xol.viewpagerfragment D/ViewPagerFragment: onPause: A
    onStop: A
01-24 14:10:40.814 1805-1805/com.xol.viewpagerfragment D/ViewPagerFragment: onDestroyView: A
01-24 14:10:40.815 1805-1805/com.xol.viewpagerfragment D/ViewPagerFragment: onCreateView: D
01-24 14:10:40.817 1805-1805/com.xol.viewpagerfragment D/ViewPagerFragment: onViewCreated: D
    onActivityCreated: D
01-24 14:10:40.818 1805-1805/com.xol.viewpagerfragment D/ViewPagerFragment: onStart: D
    onResume: D
    
// 上面为viewPager滑动到C Fragment的日志输出
01-24 14:10:41.618 1805-1805/com.xol.viewpagerfragment D/ViewPagerFragment: onCreate: E
    onPause: B
01-24 14:10:41.619 1805-1805/com.xol.viewpagerfragment D/ViewPagerFragment: onStop: B
    onDestroyView: B
01-24 14:10:41.620 1805-1805/com.xol.viewpagerfragment D/ViewPagerFragment: onCreateView: E
01-24 14:10:41.622 1805-1805/com.xol.viewpagerfragment D/ViewPagerFragment: onViewCreated: E
01-24 14:10:41.623 1805-1805/com.xol.viewpagerfragment D/ViewPagerFragment: onActivityCreated: E
    onStart: E
01-24 14:10:41.624 1805-1805/com.xol.viewpagerfragment D/ViewPagerFragment: onResume: E

// 上面为viewPager滑动到D Fragment的日志输出
01-24 14:10:42.720 1805-1805/com.xol.viewpagerfragment D/ViewPagerFragment: onPause: C
    onStop: C
    onDestroyView: C
// 上面为viewPager滑动到E Fragment的日志输出

日志分析

  • 打开activity,viewPager没有滑动的时候,由于PagerFragmentAdapter 默认缓存三个Fragment(当前页和左右页面) 第一次当前页面为A Fragment 缓存右边页面为B Fragment;故开始日志输出为A-onCreate-onCreateView-onViewCreated-onActivityCreated-onStart-onResume B-onCreate-onCreateView-onViewCreated-onActivityCreated-onStart-onResume
  • 当viewPager滑动到B Fragment时候,由于默认缓存三个Fragment,会预先生成C Fragment,故日志输出为C-onCreate-onCreateView-onViewCreated-onActivityCreated-onStart-onResume
  • 当viewPager滑动到C Fragment,会预先生成D Fragment,移除A-Fragment(内存中依然存在);故日志输出为D-onCreate-onCreateView-onViewCreated-onActivityCreated-onStart-onResume A-onPause-onStop-onDestroyView
  • 当viewPager由C Fragment 动到B Fragment时,A Fragment 会走 onCreateView-onViewCreated-onActivityCreated-onStart-onResume

总结
ViewPager 结合PagerFragmentAdapter滑动的过程中,默认会生成三个Fragment(当在viewPager开始和结尾的时候默认只会生成两个Fragment)包括当前Fragment和左右位置的Fragment,并且在滑动的过程中,会预先生成下一个Fragment,并销毁多余的Fragment,列当滑到C Fragment 的时候,A Fragment 会从view层面销毁,但并不会走Fragment的onDestroy和onDetach周期方法,当我们反向滑动,并重新预加载A Fragment时,此时 A Fragment 并不会走onAttach 和 onCreate方法,只会走onCreateView-onViewCreated-onActivityCreated-onStart-onResume

此时若想复用之前的View 可在内存中保存一个Fragment的根view,做非空判断,去复用已经创建过的view Fragment代码如下:

   public static class ViewPagerFragment extends Fragment {

        private static final String TAG = "ViewPagerFragment";
        private String tab;
        private View mRootView;

        public static Fragment createFragment(Bundle bundle) {
            Fragment fragment = new ViewPagerFragment();
            fragment.setArguments(bundle);
            return fragment;
        }

        @Override
        public void onAttach(Context context) {
            tab = getArguments().getString("tab");
            Log.d(TAG, "onAttach: "+tab);
            super.onAttach(context);
        }

        @Override
        public void onActivityCreated(@Nullable Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            Log.d(TAG, "onActivityCreated: " + tab);
        }

        @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            Log.d(TAG, "onCreate: " + tab);
        }

        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            Log.d(TAG, "onCreateView: " + tab);
            if(mRootView==null) {
                TextView textView = new TextView(container.getContext());
                FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                        ViewGroup.LayoutParams.MATCH_PARENT);
                params.gravity = Gravity.CENTER;
                textView.setPadding(25, 25, 25, 25);
                textView.setGravity(Gravity.CENTER);
                textView.setLayoutParams(params);
                textView.setText(tab);
                mRootView =textView;
            }
            return mRootView;
        }
    }

点击返回键关闭Activity日志输出

01-24 14:29:39.719 3087-3087/com.xol.viewpagerfragment D/ViewPagerFragment: onPause: D
01-24 14:29:39.721 3087-3087/com.xol.viewpagerfragment D/ViewPagerFragment: onPause: E
01-24 14:29:40.567 3087-3087/com.xol.viewpagerfragment D/ViewPagerFragment: onStop: D
    onStop: E
01-24 14:29:40.568 3087-3087/com.xol.viewpagerfragment D/ViewPagerFragment: onDestroyView: D
01-24 14:29:40.570 3087-3087/com.xol.viewpagerfragment D/ViewPagerFragment: onDestroy: D
    onDetach: D
    onDestroyView: E
    onDestroy: E
    onDetach: E
01-24 14:29:40.571 3087-3087/com.xol.viewpagerfragment D/ViewPagerFragment: onDestroy: A
    onDetach: A
    onDestroy: B
    onDetach: B
    onDestroy: C
01-24 14:29:40.572 3087-3087/com.xol.viewpagerfragment D/ViewPagerFragment: onDetach: C
  • 当我们关闭Fragment的宿主Activity的时候,此时,所有生成的Fragment都会走 onDestroy-onDetach方法。

总结
我们在结合ViewPager和FragmentPagerAdapter使用的时候,可以在Fragment的OnDestory或OnDetach方法中回收Fragment中的资源。

希望对您有所帮助

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值