Android ViewPager相关系列总结

作者: 蓝库知识 | 来源:发表于2018-12-12 16:45 被阅读12次
    一.ViewPager+Fragment的使用

    第一步:创建几个fragment
    第二步:实例化ViewPager,添加Adapter
    第三步:传值绑定

    public class MainActivity extends AppCompatActivity {
        private ViewPager mViewPager;
        FragmentManager fragmentManager;
        private List<Fragment> fragments = new ArrayList<>();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mViewPager = findViewById(R.id.viewPagerId);
            Fragment1 fragment1 = new Fragment1();
            Fragment2 fragment2 = new Fragment2();
            Fragment3 fragment3 = new Fragment3();
            Fragment4 fragment4 = new Fragment4();
            fragments.add(fragment1);
            fragments.add(fragment2);
            fragments.add(fragment3);
            fragments.add(fragment4);
            fragmentManager = getSupportFragmentManager();
            fragmentManager.beginTransaction();
            mViewPager.setAdapter(new ViewPagerAdapter(fragmentManager));
        }
    public class ViewPagerAdapter extends FragmentStatePagerAdapter {
    
            public ViewPagerAdapter(FragmentManager fm) {
                super(fm);
            }
            @Override
            public Fragment getItem(int i) {
                return fragments.get(i);
            }
    
            @Override
            public int getCount() {
                return fragments.size();
            }
        }
    
    二.缓存原理

    每次缓存一前一后和当前页面一共三个界面,当界面左边或者右边没有界面的时候,则一共缓存两个界面了。以这种方式加载pager会导致数据刷新不会即时。因为缓存中有的时候就不会从集合中拿,也就不会走生命周期的方法。
    解决办法:
    Android ViewPager Fragment 切换刷新数据,解决生命周期只走一次的问题

    public class Fragment1 extends Fragment {
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            return inflater.inflate(R.layout.fragment_fragment1, container, false);
        }
    
        public void onUpdate() {
            Log.d("Tina=======>", "fragment1 " + "onUpdate");
        }
    
        @Override
        public void setUserVisibleHint(boolean isVisibleToUser) {
            super.setUserVisibleHint(isVisibleToUser);
    
            if (isVisibleToUser) {
                onUpdate();
            }
    
        }
    }
    
    分析源码

    在FragmentStatePagerAdapter中有一个方法setPrimaryItem,每次切换page的前后都会调用此方法,每次显示当前界面的时候总会调用fragment.setUserVisibleHint(true);因此监听setUserVisibleHint,就可以实现数据刷新了。

    public void setPrimaryItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
            Fragment fragment = (Fragment)object;
            if (fragment != this.mCurrentPrimaryItem) {
                if (this.mCurrentPrimaryItem != null) {
                    this.mCurrentPrimaryItem.setMenuVisibility(false);
                    this.mCurrentPrimaryItem.setUserVisibleHint(false);
                }
    
                fragment.setMenuVisibility(true);
                fragment.setUserVisibleHint(true);
                this.mCurrentPrimaryItem = fragment;
            }
    
        }
    
    三.FragmentPagerAdapter与FragmentStatePagerAdapter的区别

    ViewPager中的FragmentPagerAdapter,FragmentStatePagerAdapter
    缓存界面的个数是有限的,所以被挤出来的界面是要销毁掉的,FragmentPagerAdapter不会走onDestroy,所以不会完全被回收,但是FragmentStatePagerAdapter会走ondestroy彻底销毁掉。

    四.Viewpager自动轮播

    viewPager自动轮播的实现网上估计很多,这里的注意点发生的情景为轮播图的数量会发生变化的情况,在使用hander发送消息的时候,需要注意一点,要不然会使得项目崩溃。

     if (mHandler == null) {
                mHandler = new Handler() {
                    @Override
                    public void handleMessage(Message msg) {
                        // 得到当前的页面
                        int currentItem = pager.getCurrentItem();
                        // 确定下一个页面
                        //如果轮播图为空
                        if (data.getSlider() == null || data.getSlider().isEmpty()) {
                        } else {
                            pager.setVisibility(View.VISIBLE);
                            if (currentItem < data.getSlider().size() - 1) {
                                currentItem++;
                            } else {
                                currentItem = 0;
                            }
                        }
                        // 设置页面
                        if (currentItem == 0 || data.getSlider().size() - 1 < currentItem) {
                            pager.setCurrentItem(0, false);
                        } else {
                            pager.setCurrentItem(currentItem);
                        }
                        //mScroller.setmDuration(800);
                        // 给自己发消息
                        mHandler.sendEmptyMessageDelayed(0, 3600);
                    }
                };
                mHandler.sendEmptyMessageDelayed(0, 5600);
            }
    

    注意第19行,如果不判断currentItem是否越界,则会出现崩溃。因为,如果轮播图的个数从4减少到2,当轮播图自动滑到了第二张,此时currentItem计算完后值为2,也就是接下来会显示第三张,但是data中只有两个数据已经没有第三张了,故setCurrentItem(2)的时候,数组会发生越界,导致崩溃。
    喵印~~

    相关文章

      网友评论

        本文标题:Android ViewPager相关系列总结

        本文链接:https://www.haomeiwen.com/subject/aadphqtx.html