美文网首页Android 学习资源程序Android
Android 教你简单封装多Fragment切换

Android 教你简单封装多Fragment切换

作者: DevSiven | 来源:发表于2016-08-23 10:02 被阅读4913次

《Android 教你简单封装多Fragment切换》

转载请注明来自 傻小孩b_移动开发
http://www.jianshu.com/users/d388bcf9c4d3
喜欢的可以关注我,不定期总结文章!您的支持是我的动力哈!

一、应用场景

viewpager+Fragment实现页面切换。在日常的应用首页、广告轮播、欢迎页、图片切换等等应用上,非常广泛、非常广泛(真的非常广泛哈)。前期刚好也写了一篇在多Fragment也面切换的时候也许会出现getActivity()为null的情况,有需要的的读者可以看下《Android 那些年,处理getActivity()为null的日子》。

对于多页面切换,比较常见程序猿的写法是,举个例子:

(1)初始化Fragment

       Tab1Fragment tab1Fragment = new Tab1Fragment();
       Tab2Fragment tab2Fragment = new Tab2Fragment();
       Tab3Fragment tab3Fragment = new Tab3Fragment();

(2)将Fragment存储在List后,初始化ViewPager适配器

        fragmentList.add(tab1Fragment);
        fragmentList.add(tab2Fragment);
        fragmentList.add(tab3Fragment);
        viewAdapter = new MainPagerAdapter(getSupportFragmentManager(),fragmentList,titleList);
        viewPager.setAdapter(viewAdapter);
        viewPager.setCurrentItem(0);//默認選中第一個

(3)通过实现setOnPageChangeListener接口,实现切换监听

   viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                
            }

            @Override
            public void onPageSelected(int position) {

            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

二、应用ing->代码解说

事不宜迟,代码直接解说:
(1)定义一个存储Fragment实体类

 /**
     * ViewPageInformation
     */
    public static class ViewPageInfo {
        public String tag;
        public View view;
        public Fragment fragment;

        public ViewPageInfo(String tag, Fragment fragment){
            this.tag = tag;
            this.fragment = fragment;
        }
    }

其中tag用于Fragment标识,可以作为标题,看各位程序猿怎么定义。view指的是Fragment绑定的视图。fragment就不用多说啦哈。

(2)定义一个基类BaseTabFragment,适用于多Fragment切换的场景。


/**
 * 应用在需要多个fragment场景,ViewPager作为存储容器 viewpager依赖父类
 * Created by wsy on 2016/8/15.
 */
public abstract class BaseTabFragment extends BaseFragment{

    private ViewPager viewPager;
    private List<ViewPageInfo> fragList;
    protected FragmentStatePagerAdapter mAdapter;

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        viewPager = (ViewPager) view.findViewById(R.id.viewpager);

        if (mAdapter == null){
            fragList = new ArrayList<>();
            addSubViewTab();
            mAdapter = new FragmentStatePagerAdapter(getFragmentManager()) {
                @Override
                public Fragment getItem(int position) {
                    return fragList.get(position).fragment;
                }

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

                @Override
                public CharSequence getPageTitle(int position) {
                    return fragList.get(position).tag;
                }


            };
            if (viewPager !=null) {
                viewPager.setAdapter(mAdapter);
                loadFinishView(viewPager, mAdapter);
            }

        }else{
            if (viewPager !=null) {
                viewPager.setAdapter(mAdapter);
                loadFinishView(viewPager, mAdapter);
            }
        }
    }

    public FragmentStatePagerAdapter getmAdapter() {
        return mAdapter;
    }

    public abstract void addSubViewTab();

    public abstract void loadFinishView(ViewPager viewPager,FragmentStatePagerAdapter mAdapter);

    public void addTab(String tag, Class<? extends Fragment> fragment){
        fragList.add(new ViewPageInfo(tag, Fragment.instantiate(getActivity(), fragment.getName())));
    }

    /**
     * ViewPageInformation
     */
    public static class ViewPageInfo {
        public String tag;
        public View view;
        public Fragment fragment;

        public ViewPageInfo(String tag, Fragment fragment){
            this.tag = tag;
            this.fragment = fragment;
        }
    }
}


首先觉得切换视图是什么由继承于这个父类的子类所有决定,这里抽象了** addSubViewTab loadFinishView** 两个方法出来由子类去实现,** addSubViewTab** 主要用于子类决定初始化什么Fragment视图,** loadFinishView** 是在加载好Fragment视图后具体要干什么(比如ViewPager配置、Fragment视图操作等等)。因为这个代码是笔者配合tabLayout所抽象出来的一个父类。当然,在日常开发中,程序猿们可以将BaseFragment换成自己的基类Fragment。

(3)怎么使用?
使用很简单,在初始化这个Fragment的时候,实现addSubViewTab抽象方法即可,具体如下:

        mainTabFragment = new MainTabFragment() {
            @Override
            public void addSubViewTab() {
                //初始化视图 调用addTab
                addTab("标题1",Tab1Fragment.class);
                addTab("标题2",Tab2Fragment.class);
                addTab("标题3",Tab3Fragment.class);
            }

            @Override
            public void loadFinishView(ViewPager viewPager, FragmentStatePagerAdapter mAdapter) {
                mViewPager = viewPager;
               //加载好视图啦,想做什么做什么,都返回给你啦
            }

        };

        getSupportFragmentManager().beginTransaction().add(R.id.test_contanter,mainTabFragment).commit();
  

三、应用ed->实现效果

这里笔者实现了一个启动欢迎界面,并且加入了笔者个人上线应用 爱游记(欢迎吐槽使用,报bug哈哈,会用一两个月时间改版,到时候开源~)

运行效果如下:


爱游记欢迎.gif

四、总结

打下预告,最近一直在看Retrofit2.0,后面想写几篇关于Retrofit2.0的文章。好几天没总结笔记T T。今天大概讲了简单封装多Fragment切换,希望可以帮助各位读者~共勉!有什么问题意见也尽管提哈!

源码地址:

Android 教你简单封装多Fragment切换

傻小孩b mark
共勉,写给在成长路上奋斗的你

喜欢就为我点下喜欢吧:-D,感谢各位读者阅读。

相关文章

网友评论

  • 65773f55f7fc:fragment怎么显示出Activity里所有的内容
    DevSiven: @敏捷的宝宝 什么意思?
  • 217cce305b3c:如果Fragment数量比较多,不知这种方式是否会有占用内存过多的问题?
    DevSiven:@奇幻森林 如果数量多,又不释放,肯定会有这种内存溢出的情况。FragmentStatePagerAdapter有提供setOffscreenPageLimit可以设置限制fragment缓存数量,多的话,在没有被显示的时候会被销毁,再次显示会再次加载。这样可以一定程度防止内存溢出。当然,如果我们作为主界面,当然希望不被重新加载啦,所以作为主界面的时候,还是多注意这种问题的~
  • museum:mainTabFragment = new MainTabFragment() 有问题
    黑发长衣:java.lang.IllegalStateException: Fragment null must be a public static class to be properly recreated from instance state. 创建时 会出这样的问题?
  • Tang1024:写法很巧妙,点赞:smile::stuck_out_tongue:
    DevSiven:@撒旦之恋歌 谢谢支持~
  • Wang_Yi:Y(^_^)Y6699
    DevSiven:@donnnn :relaxed:
  • bb6bc6959edd:实用!
    DevSiven:@呐抹阳光 谢谢支持!
  • chenyk:谢谢分享
    DevSiven: @chenyk 谢谢老板
  • hackest:用SparseArray 优化是不是比list更省内存呢?
    DevSiven:@hackest SparseArray性能高点,例如定义10个内存空间,只实例化的2个。剩下8个不会占用内存空间。

本文标题:Android 教你简单封装多Fragment切换

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