一、概念
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