新建一个activity,命名为FragmentDynamicActivity,如下:

public class FragmentDynamicActivity extends AppCompatActivity {
    private static final String TAG  = "FragmentDynamicActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fragment_dynamic);
        Log.d(TAG, "onCreate");
        initPagerStrip();
        initViewPager();
    }

    private void initPagerStrip() {
        PagerTabStrip pts_tab = findViewById(R.id.pts_tab);
        pts_tab.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);
        pts_tab.setTextColor(Color.BLACK);
    }

    private void initViewPager() {
        ArrayList<GoodsInfo> goodsList = GoodsInfo.getDefaultList();
        MobilePagerAdapter adapter = new MobilePagerAdapter(getSupportFragmentManager(), goodsList);
        ViewPager vp_content = findViewById(R.id.vp_content);
        vp_content.setAdapter(adapter);
        vp_content.setCurrentItem(0);
    }

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

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

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

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

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

FragmentDynamicActivity对应的布局文件为activity_fragment_dynamic,如下:

<?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">

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/vp_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <androidx.viewpager.widget.PagerTabStrip
            android:id="@+id/pts_tab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </androidx.viewpager.widget.ViewPager>

</LinearLayout>

FragmentDynamicActivity 对应的适配器为MobilePagerAdapter,继承于FragmentStatePagerAdapter,如下

public class MobilePagerAdapter extends FragmentStatePagerAdapter {
    private ArrayList<GoodsInfo> mGoodsList = new ArrayList<GoodsInfo>();

    public MobilePagerAdapter(@NonNull FragmentManager fm, ArrayList<GoodsInfo> mGoodsList) {
        super(fm);
        this.mGoodsList = mGoodsList;
    }

    @NonNull
    @Override
    public Fragment getItem(int position) {
        return DynamicFragment.newInstance(position, mGoodsList.get(position).pic, mGoodsList.get(position).desc);
    }

    @Override
    public int getCount() {
        return mGoodsList.size();
    }

    @Nullable
    @Override
    public CharSequence getPageTitle(int position) {
        return mGoodsList.get(position).name;
    }
}

MobilePagerAdapter中用到的碎片为DynamicFragment,如下:

public class DynamicFragment extends Fragment {
    private static final String TAG = "DynamicFragment";
    protected View mView;
    protected Context mContext;
    private int mPosition;
    private int mImageId;
    private String mDesc;

    public static DynamicFragment newInstance(int position, int image_id, String desc) {
        DynamicFragment fragment = new DynamicFragment();
        Bundle bundle = new Bundle();
        bundle.putInt("position", position);
        bundle.putInt("image_id", image_id);
        bundle.putString("desc", desc);
        fragment.setArguments(bundle);
        return fragment;
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        mContext = getContext();
        if (getArguments() != null) {
            mPosition = getArguments().getInt("position");
            mImageId = getArguments().getInt("image_id");
            mDesc = getArguments().getString("desc");
        }
        mView = inflater.inflate(R.layout.fragment_dynamic, container, false);
        ImageView iv_pic = mView.findViewById(R.id.iv_pic);
        TextView tv_desc = mView.findViewById(R.id.tv_desc);
        iv_pic.setImageResource(mImageId);
        tv_desc.setText(mDesc);
        Log.d(TAG, "onCreateView position = " + mPosition);
        return mView;
    }

    // 与activity结合。可在该方法中实例化activity的一个回调对象,再Fragment中调用activity的回调方法
    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        Log.d(TAG, "onAttach position = " + mPosition);
    }

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

    // 在活动页面创建完毕后调用
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Log.d(TAG, "onActivityCreated position = " + mPosition);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy position = " + mPosition);
    }

    // 回收碎片视图
    @Override
    public void onDestroyView() {
        super.onDestroyView();
        Log.d(TAG, "onDestroyView position = " + mPosition);
    }

    // 与activity分离
    @Override
    public void onDetach() {
        super.onDetach();
        Log.d(TAG, "onDetach position = " + mPosition);
    }

    @Override
    public void onPause() {
        super.onPause();
        Log.d(TAG, "onPause position = " + mPosition);
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.d(TAG, "onResume position = " + mPosition);
    }

    @Override
    public void onStart() {
        super.onStart();
        Log.d(TAG, "onStart position = " + mPosition);
    }

    @Override
    public void onStop() {
        super.onStop();
        Log.d(TAG, "onStop position = " + mPosition);
    }
}

DynamicFragment对应的布局文件为:fragment_dynamic,如下:

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

    <ImageView
        android:id="@+id/iv_pic"
        android:layout_width="match_parent"
        android:layout_height="360dp"
        android:scaleType="fitCenter" />

    <TextView
        android:id="@+id/tv_desc"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:textColor="@color/contentGray"
        android:textSize="17sp" />

</LinearLayout>

用到的模型为GoodsInfo,如下:

GoodsInfo模型

效果图如下:

生命周期的效果如下:

  • 左边的图是进入FragmentDynamicActivity的效果:
  • 右边的图是离开FragmentDynamicActivity的效果:
  • 左边上方的图是滑动到第二张图的效果:
  • 左边下方的图是滑动到第三张图的效果:
  • 右边上方的图是回到第二张图的效果:
  • 右边下方的图是回到第一张的效果:

总结如下:

  • 动态注册时,Fragment的 onCreate 操作再 activity 之后,其余操作的先后顺序与静态注册时保持一致
  • 进入第一个Fragment,实际上只加载了第一页和第二页,并没有加载全部的Fragment。
    • 无论当前处于那一页,系统都只会加载当前页和相邻的前后两页,总共加在不超过三页。
    • 一旦发生页面切换,相邻页面被加载,非相邻页就被回收
    • 这么做,节省了系统资源,避免所有Fragment一起加载造成资源浪费,而这正是ViewPager的缺点