控件 -- ViewPager

一、概念

ViewPager是android扩展包v4包中的类,这个类可以让用户左右切换当前的View。ViewPager类直接继承了ViewGroup类,所以它是一个容器类,可以在其中添加其他的View类。

ViewPager类需要一个PagerAdapter适配器类给它提供数据。ViewPager经常和Fragment一起使用,并且提供了专门的FragmentPagerAdapter和FragmentStatePagerAdapter类供Fragment中的ViewPager使用。

二、适配器

PagerAdapter

  • instantiateItem():
    instantiateItem()做了两件事,将当前视图添加到container中,并返回当前View。也就是说,instantiateItem()的功能是创建指定位置的页面视图,并且适配器有责任增加即将创建的View视图添加到这里给定的container中,它的返回值代表新增视图页面的Object(Key),这里没必要非要返回视图本身,也可以返回可以代表当前页面的任意值,只要可以与你增加的View一一对应即可,比如position变量也可以作为Key。
  • isViewFromObject():
    该方法用来判断instantiateItem()所返回来的Key与一个页面视图是否是代表的同一个视图(即它俩是否是对应的,对应的表示同一个View),如果对应的是同一个View返回true,否则返回false。
  • destroyItem():
    该方法的功能是移除一个给定位置的页面,适配器有责任从容器中删除这个视图,这是为了确保在finishUpdate(viewGroup)返回时视图能够被移除。
//ViewPagerAdapter
public class ViewPagerAdapter extends PagerAdapter {
    private static final String TAG = "ViewPagerAdapter";
    private List<View> mViewList;

    public ViewPagerAdapter(List<View> mViewList) {
        this.mViewList = mViewList;
    }

    @Override
    public int getCount() {//必须实现
        int count = mViewList.size();
        //Log.d(TAG, "zwm, getCount: " + count);
        return count;
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {//必须实现
        boolean isViewFromObject = (view == object);
        //Log.d(TAG,"zwm, isViewFromObject: " + isViewFromObject);
        return isViewFromObject;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {//必须实现,实例化
        Log.d(TAG,"zwm, instantiateItem, position: " + position);
        container.addView(mViewList.get(position));
        return mViewList.get(position);
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {//必须实现,销毁
        Log.d(TAG,"zwm, destroyItem, position: " + position);
        container.removeView(mViewList.get(position));
    }
}

//activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <androidx.viewpager.widget.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</FrameLayout>

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

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d(TAG, "zwm, onCreate");
        List<View> list = new ArrayList<>();
        ViewPager viewPager = findViewById(R.id.view_pager);
        ImageView imageView = new ImageView(this);
        imageView.setImageResource(R.drawable.ic_launcher);
        list.add(imageView);
        ImageView imageView2 = new ImageView(this);
        imageView2.setImageResource(R.drawable.ic_launcher);
        list.add(imageView2);
        ImageView imageView3 = new ImageView(this);
        imageView3.setImageResource(R.drawable.ic_launcher);
        list.add(imageView3);
        ViewPagerAdapter adapter = new ViewPagerAdapter(list);
        viewPager.setAdapter(adapter);
    }
}

//输出log
2020-01-21 11:04:13.320 9182-9182/com.example.sourcecodetest D/MyApplication: zwm, onCreate //初始启动
2020-01-21 11:04:14.869 9182-9182/com.example.sourcecodetest D/MainActivity: zwm, onCreate
2020-01-21 11:04:15.981 9182-9182/com.example.sourcecodetest D/ViewPagerAdapter: zwm, instantiateItem, position: 0 //初始启动,显示位置0,创建位置0对象
2020-01-21 11:04:15.982 9182-9182/com.example.sourcecodetest D/ViewPagerAdapter: zwm, instantiateItem, position: 1 //初始启动,显示位置0,创建位置1对象
2020-01-21 11:04:22.658 9182-9182/com.example.sourcecodetest D/ViewPagerAdapter: zwm, instantiateItem, position: 2 //滑动,显示位置1,创建位置2对象
2020-01-21 11:04:25.981 9182-9182/com.example.sourcecodetest D/ViewPagerAdapter: zwm, destroyItem, position: 0 //滑动,显示位置2,销毁位置0对象

FragmentPagerAdapter

//fragment_main.xml
<?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">
    <TextView
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This is one fragment layout"/>
</LinearLayout>

//OneFragment
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

public class OneFragment extends Fragment {
    private static final String TAG = "OneFragment";
    private int args = -1;

    public static OneFragment newInstance(int args){
        Log.d(TAG, "zwm, newInstance, args: " + args);
        OneFragment oneFragment = new OneFragment();
        Bundle bundle = new Bundle();
        bundle.putInt("someArgs", args);
        oneFragment.setArguments(bundle);
        return oneFragment;
    }

    @Override
    public void onInflate(@NonNull Context context, @NonNull AttributeSet attrs, @Nullable Bundle savedInstanceState) {
        super.onInflate(context, attrs, savedInstanceState);
        Log.d(TAG, "zwm, onInflate");
    }

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

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Bundle bundle = getArguments();
        int args = -1;
        if(bundle != null) {
            args = bundle.getInt("someArgs");
            this.args = args;
        }
        Log.d(TAG, "zwm, onCreate, args: " + args);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Log.d(TAG, "zwm, onCreateView, args: " + args);
        View contentView = inflater.inflate(R.layout.fragment_main, null);
        return contentView;
    }

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

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

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

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

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

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

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

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

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

//ViewPagerAdapter
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;

public class ViewPagerAdapter extends FragmentPagerAdapter {
    private static final String TAG = "ViewPagerAdapter";
    public List<Fragment> fragmentList;

    public ViewPagerAdapter(FragmentManager fm, List<Fragment> fragmentList) {
        super(fm);
        this.fragmentList = fragmentList;
    }

    @Override
    public Fragment getItem(int arg0) {
        return fragmentList.get(arg0); //显示第几个页面
    }

    @Override
    public int getCount() {
        return fragmentList.size(); //有几个页面
    }
}

//activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <androidx.viewpager.widget.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</FrameLayout>

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

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d(TAG, "zwm, onCreate");
        ViewPager viewPager= findViewById(R.id.view_pager);
        List<Fragment> list = new ArrayList<>();
        Fragment fragment1 = OneFragment.newInstance(111);
        list.add(fragment1);
        Fragment fragment2 = OneFragment.newInstance(222);
        list.add(fragment2);
        Fragment fragment3 = OneFragment.newInstance(333);
        list.add(fragment3);
        ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager(), list);
        viewPager.setAdapter(adapter);
        viewPager.addOnPageChangeListener(new PageChangeListener());
    }

    private static class PageChangeListener implements ViewPager.OnPageChangeListener{
        private static final String TAG = "PageChangeListener";

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            Log.d(TAG, "zwm, onPageScrolled, position: " + position);
        }

        @Override
        public void onPageSelected(int position) {
            Log.d(TAG, "zwm, onPageSelected, position: " + position);
        }

        @Override
        public void onPageScrollStateChanged(int state) {
            Log.d(TAG, "zwm, onPageScrollStateChanged, state: " + state);
        }
    }
}

//输出log
2020-01-21 13:26:07.233 21140-21140/com.example.sourcecodetest D/MyApplication: zwm, onCreate //初始化
2020-01-21 13:26:07.507 21140-21140/com.example.sourcecodetest D/MainActivity: zwm, onCreate
2020-01-21 13:26:07.510 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, newInstance, args: 111
2020-01-21 13:26:07.511 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, newInstance, args: 222
2020-01-21 13:26:07.512 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, newInstance, args: 333
2020-01-21 13:26:07.588 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onAttach
2020-01-21 13:26:07.589 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onCreate, args: 111 //初始化时,显示位置0,添加位置0的fragment
2020-01-21 13:26:07.589 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onAttach
2020-01-21 13:26:07.589 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onCreate, args: 222 //初始化时,显示位置0,添加位置1的fragment
2020-01-21 13:26:07.590 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onCreateView, args: 111
2020-01-21 13:26:07.598 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onViewCreated, args: 111
2020-01-21 13:26:07.598 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onActivityCreated, args: 111
2020-01-21 13:26:07.599 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onStart, args: 111
2020-01-21 13:26:07.599 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onResume, args: 111
2020-01-21 13:26:07.599 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onCreateView, args: 222
2020-01-21 13:26:07.603 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onViewCreated, args: 222
2020-01-21 13:26:07.603 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onActivityCreated, args: 222
2020-01-21 13:26:07.603 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onStart, args: 222
2020-01-21 13:26:07.604 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onResume, args: 222
2020-01-21 13:26:07.721 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:26:13.747 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 1
2020-01-21 13:26:13.748 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:26:13.812 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:26:13.816 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 2
2020-01-21 13:26:13.816 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageSelected, position: 1
2020-01-21 13:26:13.829 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:26:13.912 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:26:13.928 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:26:13.944 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:26:13.962 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:26:13.979 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:26:13.995 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:26:14.011 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:26:14.028 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:26:14.079 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:26:14.096 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:26:14.212 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 0
2020-01-21 13:26:14.213 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onAttach
2020-01-21 13:26:14.214 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onCreate, args: 333 //切换,显示位置1,添加位置2的fragment
2020-01-21 13:26:14.215 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onCreateView, args: 333
2020-01-21 13:26:14.223 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onViewCreated, args: 333
2020-01-21 13:26:14.223 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onActivityCreated, args: 333
2020-01-21 13:26:14.224 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onStart, args: 333
2020-01-21 13:26:14.224 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onResume, args: 333
2020-01-21 13:26:17.605 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 1
2020-01-21 13:26:17.606 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:26:17.620 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:26:17.637 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:26:17.669 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:26:17.680 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:26:17.681 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 2
2020-01-21 13:26:17.682 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageSelected, position: 2
2020-01-21 13:26:17.685 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:26:17.887 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:26:17.903 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 2
2020-01-21 13:26:18.003 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 0
2020-01-21 13:26:18.005 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onPause, args: 111 //切换,显示位置2,销毁位置0的fragment的View,注意没有detach fragment
2020-01-21 13:26:18.005 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onStop, args: 111
2020-01-21 13:26:18.006 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onDestroyView, args: 111
2020-01-21 13:26:24.352 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 1
2020-01-21 13:26:24.353 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:26:24.366 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:26:24.370 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 2
2020-01-21 13:26:24.370 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageSelected, position: 1
2020-01-21 13:26:24.383 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:26:24.449 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:26:24.467 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:26:24.684 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:26:24.800 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 0
2020-01-21 13:26:24.801 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onCreateView, args: 111 //切换,显示位置1,创建位置0的fragment的View
2020-01-21 13:26:24.811 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onViewCreated, args: 111
2020-01-21 13:26:24.811 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onActivityCreated, args: 111
2020-01-21 13:26:24.812 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onStart, args: 111
2020-01-21 13:26:24.812 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onResume, args: 111
2020-01-21 13:26:26.305 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 1
2020-01-21 13:26:26.306 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:26:26.338 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:26:26.342 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 2
2020-01-21 13:26:26.343 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageSelected, position: 0
2020-01-21 13:26:26.353 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:26:26.455 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:26:26.470 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:26:26.621 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:26:26.721 21140-21140/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 0
2020-01-21 13:26:26.722 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onPause, args: 333 //切换,显示位置0,销毁位置2的fragment的View,注意没有detach fragment
2020-01-21 13:26:26.723 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onStop, args: 333
2020-01-21 13:26:26.723 21140-21140/com.example.sourcecodetest D/OneFragment: zwm, onDestroyView, args: 333

FragmentStatePagerAdapter

实现同FragmentPagerAdapter。

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;

public class ViewPagerAdapter extends FragmentStatePagerAdapter {
    private static final String TAG = "ViewPagerAdapter";
    public List<Fragment> fragmentList;

    public ViewPagerAdapter(FragmentManager fm, List<Fragment> fragmentList) {
        super(fm);
        this.fragmentList = fragmentList;
    }

    @Override
    public Fragment getItem(int arg0) {
        return fragmentList.get(arg0); //显示第几个页面
    }

    @Override
    public int getCount() {
        return fragmentList.size(); //有几个页面
    }
}

//输出log
2020-01-21 13:42:52.090 21899-21899/com.example.sourcecodetest D/MyApplication: zwm, onCreate //初始化
2020-01-21 13:42:53.315 21899-21899/com.example.sourcecodetest D/MainActivity: zwm, onCreate
2020-01-21 13:42:53.319 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, newInstance, args: 111
2020-01-21 13:42:53.320 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, newInstance, args: 222
2020-01-21 13:42:53.321 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, newInstance, args: 333
2020-01-21 13:42:54.146 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onAttach
2020-01-21 13:42:54.146 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onCreate, args: 111 //初始化时,显示位置0,添加位置0的fragment
2020-01-21 13:42:54.147 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onAttach
2020-01-21 13:42:54.147 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onCreate, args: 222 //初始化时,显示位置0,添加位置1的fragment
2020-01-21 13:42:54.148 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onCreateView, args: 111
2020-01-21 13:42:54.161 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onViewCreated, args: 111
2020-01-21 13:42:54.161 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onActivityCreated, args: 111
2020-01-21 13:42:54.161 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onStart, args: 111
2020-01-21 13:42:54.162 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onResume, args: 111
2020-01-21 13:42:54.162 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onCreateView, args: 222
2020-01-21 13:42:54.167 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onViewCreated, args: 222
2020-01-21 13:42:54.167 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onActivityCreated, args: 222
2020-01-21 13:42:54.167 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onStart, args: 222
2020-01-21 13:42:54.168 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onResume, args: 222
2020-01-21 13:42:54.272 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:42:57.758 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 1
2020-01-21 13:42:57.759 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:42:57.773 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:42:57.789 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:42:57.806 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:42:57.823 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:42:57.825 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 2
2020-01-21 13:42:57.825 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageSelected, position: 1
2020-01-21 13:42:57.839 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:42:57.856 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:42:57.872 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:42:57.889 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:42:57.906 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:42:58.073 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:42:58.106 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:42:58.222 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 0
2020-01-21 13:42:58.223 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onAttach
2020-01-21 13:42:58.223 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onCreate, args: 333 //切换,显示位置1,添加位置2的fragment
2020-01-21 13:42:58.224 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onCreateView, args: 333
2020-01-21 13:42:58.230 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onViewCreated, args: 333
2020-01-21 13:42:58.230 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onActivityCreated, args: 333
2020-01-21 13:42:58.230 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onStart, args: 333
2020-01-21 13:42:58.231 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onResume, args: 333
2020-01-21 13:43:01.831 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 1
2020-01-21 13:43:01.831 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:01.847 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:01.865 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:01.881 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:01.892 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:01.894 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 2
2020-01-21 13:43:01.894 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageSelected, position: 2
2020-01-21 13:43:01.896 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:01.913 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:01.930 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:01.947 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:01.963 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:01.980 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:01.997 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:02.147 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:02.163 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 2
2020-01-21 13:43:02.280 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 0
2020-01-21 13:43:02.282 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onPause, args: 111 //切换,显示位置2,移除位置2的fragment,注意有detach fragment
2020-01-21 13:43:02.282 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onStop, args: 111
2020-01-21 13:43:02.282 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onDestroyView, args: 111
2020-01-21 13:43:02.285 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onDestroy, args: 111
2020-01-21 13:43:02.285 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onDetach, args: 111
2020-01-21 13:43:06.772 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 1
2020-01-21 13:43:06.773 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:06.806 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:06.823 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:06.826 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 2
2020-01-21 13:43:06.826 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageSelected, position: 1
2020-01-21 13:43:06.839 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:06.922 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:06.939 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:06.956 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:06.972 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:06.989 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:07.006 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:07.022 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:07.039 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:07.056 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:07.073 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:07.089 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:07.106 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:07.123 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 13:43:07.239 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 0
2020-01-21 13:43:07.240 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onAttach
2020-01-21 13:43:07.240 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onCreate, args: 111 //切换,显示位置1,添加位置1的fragment,重新attach fragment
2020-01-21 13:43:07.241 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onCreateView, args: 111
2020-01-21 13:43:07.247 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onViewCreated, args: 111
2020-01-21 13:43:07.247 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onActivityCreated, args: 111
2020-01-21 13:43:07.247 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onStart, args: 111
2020-01-21 13:43:07.248 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onResume, args: 111
2020-01-21 13:43:12.299 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 1
2020-01-21 13:43:12.299 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:43:12.315 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:43:12.332 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:43:12.349 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:43:12.365 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:43:12.382 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:43:12.386 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 2
2020-01-21 13:43:12.386 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageSelected, position: 0
2020-01-21 13:43:12.398 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:43:12.415 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:43:12.432 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:43:12.448 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:43:12.465 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:43:12.482 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:43:12.515 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:43:12.533 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:43:12.549 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:43:12.566 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:43:12.682 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 13:43:12.815 21899-21899/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 0
2020-01-21 13:43:12.816 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onPause, args: 333 //切换,显示位置0,移除位置2的fragment,注意有detach fragment
2020-01-21 13:43:12.816 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onStop, args: 333
2020-01-21 13:43:12.816 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onDestroyView, args: 333
2020-01-21 13:43:12.818 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onDestroy, args: 333
2020-01-21 13:43:12.818 21899-21899/com.example.sourcecodetest D/OneFragment: zwm, onDetach, args: 333

三、生命周期

情况1:使用FragmentPagerAdapter、FragmentPagerStateAdapter,不设置setOffscreenPageLimit

左右滑动页面,每次只缓存下一个页面和上一个页面。间隔的点击tab,如从位于tab1的时候直接选择tab3或tab4,tab1将会被销毁。

两者的区别在于:
使用FragmentPagerAdapter的话Fragment不会detach,而使用FragmentPagerStateAdapter的话Fragment会detach。因此FragmentPagerAdapter适用于页面比较少的情况,而FragmentStatePagerAdapter适用于页面比较多的情况。

情况2:使用FragmentPagerAdapter、FragmentPagerStateAdapter,设置setOffscreenPageLimit为tab总数

创建ViewPager的时候所有页面都将创建完成,生命周期走到onResume。间隔的点击tab,如从位于tab1的时候直接选择tab3或tab4,tab1不会被销毁。

FragmentPagerAdapter和FragmentPagerStateAdapter没有区别。

情况3:进入其他页面或者用户按home键回到桌面,当前ViewPager页面变成不见状态

四、懒加载方案

//fragment_main.xml
<?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">
    <TextView
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This is one fragment layout"/>
</LinearLayout>

//OneFragment
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

public class OneFragment extends Fragment {
    private static final String TAG = "OneFragment";
    private int args = -1;
    private boolean isViewInit = false;
    private boolean isDataLoad = false;

    public static OneFragment newInstance(int args){
        Log.d(TAG, "zwm, newInstance, args: " + args);
        OneFragment oneFragment = new OneFragment();
        Bundle bundle = new Bundle();
        bundle.putInt("someArgs", args);
        oneFragment.setArguments(bundle);
        return oneFragment;
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
    }

    @Override
    public void onInflate(@NonNull Context context, @NonNull AttributeSet attrs, @Nullable Bundle savedInstanceState) {
        super.onInflate(context, attrs, savedInstanceState);
        Log.d(TAG, "zwm, onInflate");
    }

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

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Bundle bundle = getArguments();
        int args = -1;
        if(bundle != null) {
            args = bundle.getInt("someArgs");
            this.args = args;
        }
        Log.d(TAG, "zwm, onCreate, args: " + args);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Log.d(TAG, "zwm, onCreateView, args: " + args);
        View contentView = inflater.inflate(R.layout.fragment_main, null);
        isViewInit = true;
        return contentView;
    }

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

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

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

    @Override
    public void onResume() {
        super.onResume();
        Log.d(TAG, "zwm, onResume, args: " + args);
        loadData(); // 在onResume中进行数据懒加载
    }

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

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

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

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

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

    private void loadData() {
        Log.d(TAG, "zwm, loadData, isViewInit: " + isViewInit + ", isDataLoad: " + isDataLoad);
        if(isViewInit && !isDataLoad) {
            Log.d(TAG, "zwm, loading data...");
            isDataLoad = true;
        }
    }
}

//ViewPagerAdapter
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;

public class ViewPagerAdapter extends FragmentPagerAdapter {
    private static final String TAG = "ViewPagerAdapter";
    public List<Fragment> fragmentList;

    public ViewPagerAdapter(FragmentManager fm, int behavior, List<Fragment> fragmentList) {
        super(fm, behavior);
        this.fragmentList = fragmentList;
    }

    @Override
    public Fragment getItem(int arg0) {
        return fragmentList.get(arg0); //显示第几个页面
    }

    @Override
    public int getCount() {
        return fragmentList.size(); //有几个页面
    }
}

//activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <androidx.viewpager.widget.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</FrameLayout>

//MainActivity
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.ViewPager;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;

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

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d(TAG, "zwm, onCreate");
        ViewPager viewPager= findViewById(R.id.view_pager);
        List<Fragment> list = new ArrayList<>();
        Fragment fragment1 = OneFragment.newInstance(111);
        list.add(fragment1);
        Fragment fragment2 = OneFragment.newInstance(222);
        list.add(fragment2);
        Fragment fragment3 = OneFragment.newInstance(333);
        list.add(fragment3);
        //为适配器设置FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT参数
        ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager(), FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT, list);
        viewPager.setOffscreenPageLimit(3);
        viewPager.setAdapter(adapter);
        viewPager.addOnPageChangeListener(new PageChangeListener());
    }

    private static class PageChangeListener implements ViewPager.OnPageChangeListener{
        private static final String TAG = "PageChangeListener";

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            Log.d(TAG, "zwm, onPageScrolled, position: " + position);
        }

        @Override
        public void onPageSelected(int position) {
            Log.d(TAG, "zwm, onPageSelected, position: " + position);
        }

        @Override
        public void onPageScrollStateChanged(int state) {
            Log.d(TAG, "zwm, onPageScrollStateChanged, state: " + state);
        }
    }
}

//输出log
2020-01-21 14:17:23.972 28151-28151/com.example.sourcecodetest D/MainActivity: zwm, onCreate //初始化
2020-01-21 14:17:23.972 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, newInstance, args: 111
2020-01-21 14:17:23.972 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, newInstance, args: 222
2020-01-21 14:17:23.973 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, newInstance, args: 333
2020-01-21 14:17:24.054 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, onAttach
2020-01-21 14:17:24.055 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, onCreate, args: 111 //初始化时,显示位置0,添加位置0的fragment
2020-01-21 14:17:24.055 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, onAttach
2020-01-21 14:17:24.055 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, onCreate, args: 222 //初始化时,显示位置0,添加位置1的fragment
2020-01-21 14:17:24.056 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, onAttach
2020-01-21 14:17:24.056 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, onCreate, args: 333 //初始化时,显示位置0,添加位置2的fragment
2020-01-21 14:17:24.056 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, onCreateView, args: 111
2020-01-21 14:17:24.061 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, onViewCreated, args: 111
2020-01-21 14:17:24.061 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, onActivityCreated, args: 111
2020-01-21 14:17:24.062 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, onStart, args: 111
2020-01-21 14:17:24.062 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, onCreateView, args: 222
2020-01-21 14:17:24.067 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, onViewCreated, args: 222
2020-01-21 14:17:24.067 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, onActivityCreated, args: 222
2020-01-21 14:17:24.067 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, onStart, args: 222
2020-01-21 14:17:24.068 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, onCreateView, args: 333
2020-01-21 14:17:24.072 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, onViewCreated, args: 333
2020-01-21 14:17:24.072 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, onActivityCreated, args: 333
2020-01-21 14:17:24.072 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, onStart, args: 333
2020-01-21 14:17:24.072 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, onResume, args: 111 //显示位置0,只回调位置0的fragment的onResume方法
2020-01-21 14:17:24.073 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, loadData, isViewInit: true, isDataLoad: false //位置0的fragment未加载数据则进行加载
2020-01-21 14:17:24.073 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, loading data...
2020-01-21 14:17:24.147 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 14:17:34.686 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 1
2020-01-21 14:17:34.687 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 14:17:34.752 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 14:17:34.761 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 14:17:34.763 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 2
2020-01-21 14:17:34.763 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageSelected, position: 1
2020-01-21 14:17:34.781 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 14:17:34.799 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 14:17:34.815 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 14:17:34.850 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 14:17:34.866 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 14:17:34.984 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 14:17:35.000 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 14:17:35.099 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 0
2020-01-21 14:17:35.100 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, onPause, args: 111
2020-01-21 14:17:35.100 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, onResume, args: 222 //切换,显示位置1,只回调位置1的fragment的onResume方法
2020-01-21 14:17:35.100 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, loadData, isViewInit: true, isDataLoad: false //位置1的fragment未加载数据则进行加载
2020-01-21 14:17:35.100 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, loading data...
2020-01-21 14:17:39.125 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 1
2020-01-21 14:17:39.125 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 14:17:39.191 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 14:17:39.207 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 14:17:39.210 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 2
2020-01-21 14:17:39.210 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageSelected, position: 2
2020-01-21 14:17:39.223 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 14:17:39.358 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 14:17:39.374 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 2
2020-01-21 14:17:39.456 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 0
2020-01-21 14:17:39.457 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, onPause, args: 222
2020-01-21 14:17:39.458 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, onResume, args: 333 //切换,显示位置2,只回调位置2的fragment的onResume方法
2020-01-21 14:17:39.458 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, loadData, isViewInit: true, isDataLoad: false //位置2的fragment未加载数据则进行加载
2020-01-21 14:17:39.458 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, loading data...
2020-01-21 14:17:53.498 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 1
2020-01-21 14:17:53.499 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 14:17:53.531 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 14:17:53.549 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 14:17:53.554 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 2
2020-01-21 14:17:53.554 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageSelected, position: 1
2020-01-21 14:17:53.563 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 14:17:53.781 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 1
2020-01-21 14:17:53.896 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 0
2020-01-21 14:17:53.896 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, onPause, args: 333
2020-01-21 14:17:53.897 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, onResume, args: 222 //切换,显示位置1,只回调位置1的fragment的onResume方法
2020-01-21 14:17:53.897 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, loadData, isViewInit: true, isDataLoad: true //位置1的fragment已加载数据则不进行加载
2020-01-21 14:18:01.645 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 1
2020-01-21 14:18:01.645 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 14:18:01.677 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 14:18:01.694 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 14:18:01.706 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 14:18:01.707 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 2
2020-01-21 14:18:01.708 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageSelected, position: 0
2020-01-21 14:18:01.726 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 14:18:01.861 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0
2020-01-21 14:18:01.926 28151-28151/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrollStateChanged, state: 0
2020-01-21 14:18:01.927 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, onPause, args: 222
2020-01-21 14:18:01.928 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, onResume, args: 111 //切换,显示位置0,只回调位置0的fragment的onResume方法
2020-01-21 14:18:01.928 28151-28151/com.example.sourcecodetest D/OneFragment: zwm, loadData, isViewInit: true, isDataLoad: true //位置0的fragment已加载数据则不进行加载

五、刷新问题

现象

如果想实现ViewPager的数据刷新,在调用PageAdapter的notifyDataSetChanged()会发现并没有效果,往后滑动两页到第三页会发现,除了ViewPager默认缓存的那三页数据没有刷新之外,后面的(第三页之后)数据都是刷新了的,这时再返回第一页会发现第一页的数据也发生变化了。

分析

Viewpager的刷新过程:在每次调用PagerAdapter的notifyDataSetChanged()方法时,都会激活getItemPosition(Object object)方法,该方法会遍历ViewPager的所有Item(由缓存的Item数量决定,默认为当前页和其左右加起来共3页,这个可以自行设定,但是至少会缓存2页),为每个Item返回一个状态值(POSITION_NONE/POSITION_UNCHANGED),如果是POSITION_NONE,那么该Item会被destroyItem(ViewGroup container, int position, Object object)方法remove掉然后重新加载,如果是POSITION_UNCHANGED就不会重新加载。默认是POSITION_UNCHANGED,所以如果不重写getItemPosition(Object object)并修改返回值,就无法看到notifyDataSetChanged()的刷新效果。

方案

复写PagerAdapter的getItemPosition方法,返回POSITION_NONE。

public int getItemPosition(Object object) {    
  return POSITION_NONE;
}

//注意:要同时重写destroyItem方法
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    //把Object强转为View,然后将View从ViewGroup中清除
    container.removeView((View) object);
}

但是该方案有个很明显的缺陷,就是会刷新所有的Item,这将导致系统资源的浪费,所以这种方式不适合数据量较大的场景。

可以通过以下方式优化:
在instantiateItem()方法中给每个View添加tag(使用setTag()方法),然后在getItemPosition()方法中通过View.getTag()来判断是否是需要刷新的页面,是就返回POSITION_NONE,否就返回 POSITION_UNCHANGED。

注意:当清空数据源的时候需要返回POSITION_NONE。

if (mDataList != null && mDataList.size()==0) {
    return POSITION_NONE;
}

六、禁止过渡动画

当ViewPager绑定了TabLayout控件时,通常都有点击一个Tab实现切换ViewPager的功能,但是如果在切换时不想要那个切换动画,可以通过以下方式:

//第二个参数就是禁止滚动过渡的效果
mViewPager.setCurrentItem(1, false);

七、设置预加载页数

ViewPager默认会预加载左右两页的内容,如果想预加载更多,可以通过以下方式:

//设置缓存View的个数
mViewPager.setOffscreenPageLimit(3);

八、禁止手势左右切换

//ViewPagerEx
import androidx.viewpager.widget.ViewPager;

public class ViewPagerEx extends ViewPager {
    private boolean isPagingEnabled = true;

    public ViewPagerEx(Context context) {
        super(context);
    }
    public ViewPagerEx(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return this.isPagingEnabled && super.onTouchEvent(event);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        return this.isPagingEnabled && super.onInterceptTouchEvent(event);
    }

    public void setPagingEnabled(boolean canScroll) {
        this.isPagingEnabled = canScroll;
    }

    @Override
    public void setCurrentItem(int item, boolean smoothScroll) {
        super.setCurrentItem(item, smoothScroll);
    }
}

//fragment_main.xml
<?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">
    <TextView
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This is one fragment layout"/>
</LinearLayout>

//OneFragment
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

public class OneFragment extends Fragment {
    private static final String TAG = "OneFragment";
    private int args = -1;
    private boolean isViewInit = false;
    private boolean isDataLoad = false;

    public static OneFragment newInstance(int args){
        Log.d(TAG, "zwm, newInstance, args: " + args);
        OneFragment oneFragment = new OneFragment();
        Bundle bundle = new Bundle();
        bundle.putInt("someArgs", args);
        oneFragment.setArguments(bundle);
        return oneFragment;
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
    }

    @Override
    public void onInflate(@NonNull Context context, @NonNull AttributeSet attrs, @Nullable Bundle savedInstanceState) {
        super.onInflate(context, attrs, savedInstanceState);
        Log.d(TAG, "zwm, onInflate");
    }

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

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Bundle bundle = getArguments();
        int args = -1;
        if(bundle != null) {
            args = bundle.getInt("someArgs");
            this.args = args;
        }
        Log.d(TAG, "zwm, onCreate, args: " + args);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Log.d(TAG, "zwm, onCreateView, args: " + args);
        View contentView = inflater.inflate(R.layout.fragment_main, null);
        isViewInit = true;
        return contentView;
    }

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

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

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

    @Override
    public void onResume() {
        super.onResume();
        Log.d(TAG, "zwm, onResume, args: " + args);
        loadData(); // 在onResume中进行数据懒加载
    }

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

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

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

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

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

    private void loadData() {
        Log.d(TAG, "zwm, loadData, isViewInit: " + isViewInit + ", isDataLoad: " + isDataLoad);
        if(isViewInit && !isDataLoad) {
            Log.d(TAG, "zwm, loading data...");
            isDataLoad = true;
        }
    }
}

//ViewPagerAdapter
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;

public class ViewPagerAdapter extends FragmentPagerAdapter {
    private static final String TAG = "ViewPagerAdapter";
    public List<Fragment> fragmentList;

    public ViewPagerAdapter(FragmentManager fm, int behavior, List<Fragment> fragmentList) {
        super(fm, behavior);
        this.fragmentList = fragmentList;
    }

    @Override
    public Fragment getItem(int arg0) {
        return fragmentList.get(arg0); //显示第几个页面
    }

    @Override
    public int getCount() {
        return fragmentList.size(); //有几个页面
    }
}

//activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <com.example.sourcecodetest.ViewPagerEx
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</FrameLayout>

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

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d(TAG, "zwm, onCreate");
        final ViewPagerEx viewPager= findViewById(R.id.view_pager);
        List<Fragment> list = new ArrayList<>();
        Fragment fragment1 = OneFragment.newInstance(111);
        list.add(fragment1);
        Fragment fragment2 = OneFragment.newInstance(222);
        list.add(fragment2);
        Fragment fragment3 = OneFragment.newInstance(333);
        list.add(fragment3);
        //为适配器设置FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT参数
        ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager(), FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT, list);
        viewPager.setOffscreenPageLimit(3);
        viewPager.setAdapter(adapter);
        viewPager.addOnPageChangeListener(new PageChangeListener());

        viewPager.setPagingEnabled(false); //false表示禁止左右滑动,true表示允许左右滑动
    }

    private static class PageChangeListener implements ViewPager.OnPageChangeListener{
        private static final String TAG = "PageChangeListener";

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            Log.d(TAG, "zwm, onPageScrolled, position: " + position);
        }

        @Override
        public void onPageSelected(int position) {
            Log.d(TAG, "zwm, onPageSelected, position: " + position);
        }

        @Override
        public void onPageScrollStateChanged(int state) {
            Log.d(TAG, "zwm, onPageScrollStateChanged, state: " + state);
        }
    }
}

//输出log
2020-01-21 14:55:40.056 32750-32750/com.example.sourcecodetest D/MainActivity: zwm, onCreate
2020-01-21 14:55:40.056 32750-32750/com.example.sourcecodetest D/OneFragment: zwm, newInstance, args: 111
2020-01-21 14:55:40.056 32750-32750/com.example.sourcecodetest D/OneFragment: zwm, newInstance, args: 222
2020-01-21 14:55:40.057 32750-32750/com.example.sourcecodetest D/OneFragment: zwm, newInstance, args: 333
2020-01-21 14:55:40.089 32750-32750/com.example.sourcecodetest D/OneFragment: zwm, onAttach
2020-01-21 14:55:40.090 32750-32750/com.example.sourcecodetest D/OneFragment: zwm, onCreate, args: 111
2020-01-21 14:55:40.090 32750-32750/com.example.sourcecodetest D/OneFragment: zwm, onAttach
2020-01-21 14:55:40.090 32750-32750/com.example.sourcecodetest D/OneFragment: zwm, onCreate, args: 222
2020-01-21 14:55:40.090 32750-32750/com.example.sourcecodetest D/OneFragment: zwm, onAttach
2020-01-21 14:55:40.091 32750-32750/com.example.sourcecodetest D/OneFragment: zwm, onCreate, args: 333
2020-01-21 14:55:40.091 32750-32750/com.example.sourcecodetest D/OneFragment: zwm, onCreateView, args: 111
2020-01-21 14:55:40.096 32750-32750/com.example.sourcecodetest D/OneFragment: zwm, onViewCreated, args: 111
2020-01-21 14:55:40.097 32750-32750/com.example.sourcecodetest D/OneFragment: zwm, onActivityCreated, args: 111
2020-01-21 14:55:40.097 32750-32750/com.example.sourcecodetest D/OneFragment: zwm, onStart, args: 111
2020-01-21 14:55:40.097 32750-32750/com.example.sourcecodetest D/OneFragment: zwm, onCreateView, args: 222
2020-01-21 14:55:40.101 32750-32750/com.example.sourcecodetest D/OneFragment: zwm, onViewCreated, args: 222
2020-01-21 14:55:40.101 32750-32750/com.example.sourcecodetest D/OneFragment: zwm, onActivityCreated, args: 222
2020-01-21 14:55:40.101 32750-32750/com.example.sourcecodetest D/OneFragment: zwm, onStart, args: 222
2020-01-21 14:55:40.102 32750-32750/com.example.sourcecodetest D/OneFragment: zwm, onCreateView, args: 333
2020-01-21 14:55:40.106 32750-32750/com.example.sourcecodetest D/OneFragment: zwm, onViewCreated, args: 333
2020-01-21 14:55:40.106 32750-32750/com.example.sourcecodetest D/OneFragment: zwm, onActivityCreated, args: 333
2020-01-21 14:55:40.106 32750-32750/com.example.sourcecodetest D/OneFragment: zwm, onStart, args: 333
2020-01-21 14:55:40.106 32750-32750/com.example.sourcecodetest D/OneFragment: zwm, onResume, args: 111
2020-01-21 14:55:40.106 32750-32750/com.example.sourcecodetest D/OneFragment: zwm, loadData, isViewInit: true, isDataLoad: false
2020-01-21 14:55:40.106 32750-32750/com.example.sourcecodetest D/OneFragment: zwm, loading data...
2020-01-21 14:55:40.175 32750-32750/com.example.sourcecodetest D/PageChangeListener: zwm, onPageScrolled, position: 0

相关链接

ViewPager源码解析

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容