Fragment 嵌套 Tablayout+ViewPager+fragment 遇到的问题

来源:互联网 发布:风控模型算法spss 编辑:程序博客网 时间:2024/05/29 08:17

Fragment各种空白的问题,这个让我头疼了两天得问题终于找到了解决得办法,主要就是处理ViewPager的Adapter;

1.如果是少量的固定的Tab和Fragment,那么正常处理就行;
Adapter代码如下:

        public class Find_tab_Adapter extends FragmentPagerAdapter {    private List<Fragment> list_fragment;                         //fragment列表    private List<String> list_Title;                              //tab名的列表    public Find_tab_Adapter(FragmentManager fm, List<Fragment> list_fragment, List<String> list_Title) {        super(fm);        this.list_fragment = list_fragment;        this.list_Title = list_Title;    }    @Override    public Fragment getItem(int position) {        return list_fragment.get(position);    }    @Override    public int getCount() {        return list_Title.size();    }    @Override    public CharSequence getPageTitle(int position) {        return list_Title.get(position % list_Title.size());    }    @Override    public void destroyItem(ViewGroup container, int position, Object object) {        super.destroyItem(container, position, object);    }}

fragment中设置viewPager和TabLayout的代码:

        tab_FindFragment_title = (TabLayout) mView.findViewById(R.id.tab_FindFragment_title);        vp_FindFragment_pager = (ViewPager) mView.findViewById(R.id.vp_FindFragment_pager);        //初始化各fragment        cancleOrderStatus = new CancleOrderStatus();        completedOrderStatus = new CompletedOrderStatus();        haveOrderStatus = new HaveOrderStatus();        waitOrderStatus = new WaitOrderStatus();        //将fragment装进列表中        list_fragment = new ArrayList<>();        list_fragment.add(waitOrderStatus);        list_fragment.add(haveOrderStatus);        list_fragment.add(completedOrderStatus);        list_fragment.add(cancleOrderStatus);        //将名称加载tab名字列表,正常情况下,我们应该在values/arrays.xml中进行定义然后调用        list_title = new ArrayList<>();        list_title.add("待接单");        list_title.add("已接单");        list_title.add("已完成");        list_title.add("已取消");        //设置TabLayout的模式        tab_FindFragment_title.setTabMode(TabLayout.MODE_FIXED);        //为TabLayout添加tab名称        tab_FindFragment_title.addTab(tab_FindFragment_title.newTab().setText(list_title.get(0)));        tab_FindFragment_title.addTab(tab_FindFragment_title.newTab().setText(list_title.get(1)));        tab_FindFragment_title.addTab(tab_FindFragment_title.newTab().setText(list_title.get(2)));        tab_FindFragment_title.addTab(tab_FindFragment_title.newTab().setText(list_title.get(3)));        fAdapter = new Find_tab_Adapter(getChildFragmentManager(), list_fragment, list_title);        //viewpager加载adapter        vp_FindFragment_pager.setAdapter(fAdapter);        //tab_FindFragment_title.setViewPager(vp_FindFragment_pager);        //TabLayout加载viewpager        tab_FindFragment_title.setupWithViewPager(vp_FindFragment_pager);

这样基本代码就这样;

2.重点来了,看这里看这里。。。。。
如果你的TabLayout中和ViewPager的页面个数都是根据返回数据来定,那么按照上面的写法,百分百的出现各种让你奔溃的问题,主要原因是Adapter中的getItem()方法不会执行,Fragment空白,view控件报错等等问题,解决的办法:

1.创建Adatper继承FragmentStatePagerAdapter;public class FragmentTabAdapter extends FragmentStatePagerAdapter {//fragment列表 private List<String> list;    //tab名的列表 private List<String> list_Title;                                  public FragmentTabAdapter(FragmentManager fm, List<String> list_Title, List<String> list) {        super(fm);        this.list_Title = list_Title;        this.list = list;    }    @Override    public Fragment getItem(int position) {        TabFragment fragment = TabFragment.newInstance(list.get(position));        return fragment;    }    @Override    public Object instantiateItem(ViewGroup container, int position) {        TabFragment fragment = (TabFragment) super.instantiateItem(container, position);        fragment.updateArguments(list.get(position));        return fragment;    }    @Override    public int getItemPosition(Object object) {        return PagerAdapter.POSITION_NONE;    }    @Override    public int getCount() {        return list_Title.size();    }    @Override    public CharSequence getPageTitle(int position) {        return list_Title.get(position);    }}2.TabFragment 就是一个,根据服务器数据的多少,动态创建;TabFragment中创建两个静态方法,用于创建实例和更新传递数据; public static TabFragment newInstance(String mtd_id) {        TabFragment f = new TabFragment();        Bundle b = new Bundle();        b.putString("id", mtd_id);        f.setArguments(b);        return f;    }    public void updateArguments(String mtd_id) {        this.mtd_id = mtd_id;        Bundle args = getArguments();        if (args != null) {            args.putString("id", mtd_id);        }    } @Override    public void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        Bundle arguments = getArguments();        if (arguments != null) {            mtd_id = arguments.getString("id");        }    }3.假如HomeFragment是我们的Tablayout+viewPager的父容器,从网路获取并设置获取数据;//假如我获取到一个mgTypeList集合数据,那么就遍历该集合,添加集合信息到new的两个集合中list,list_title中;  for (ShoppingMallBean.MgTypeListBean mgTypeListBean : mgTypeList) {            list.add(mgTypeListBean.mtd_id);            list_title.add(mgTypeListBean.mg_type_name);            //为TabLayout添加tab名称            tabFindFragmentTitle.addTab(tabFindFragmentTitle.newTab().setText(mgTypeListBean.mg_type_name));        }   //设置TabLayout的模式   tabFindFragmentTitle.setTabMode(TabLayout.MODE_SCROLLABLE);        FragmentTabAdapter fAdapter = new FragmentTabAdapter(getChildFragmentManager(), list_title, list);        //viewpager加载adapter        vpFindFragmentPager.setAdapter(fAdapter);        tabFindFragmentTitle.setupWithViewPager(vpFindFragmentPager);//到这里基本就完事儿,其他的代码差不多;主要就是Adatper需要重写父类的一些方法;

3.为了效果更好,需要进行Fragment的懒加载操作,这里提供一下懒加载的代码,然后自己添加需要的其他东西; fragment继承BaseFragment,然后在lazyLoad()中加载数据,stopLoad()中停止加载数据;

public abstract class BaseFragment extends Fragment{    protected View mView;    private TextView tvTitle;    private Toolbar toolbar;    private Unbinder bind;    /**     * 视图是否已经初初始化     */    protected boolean isInit = false;    protected boolean isLoad = false;    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container,                             Bundle savedInstanceState) {            // TODO Auto-generated method stub            mView = inflater.inflate(getLayoutId(), container, false);        //StatusBarCompat.setStatusBarColor(getActivity(), R.color.color_some_tv);        bind = ButterKnife.bind(this, mView);        isInit = true;        /**初始化的时候去加载数据**/        isCanLoadData();        initView();        return mView;    }    /**     * 视图是否已经对用户可见,系统的方法     */    @Override    public void setUserVisibleHint(boolean isVisibleToUser) {        super.setUserVisibleHint(isVisibleToUser);        isCanLoadData();    }    /**     * 是否可以加载数据     * 可以加载数据的条件:     * 1.视图已经初始化     * 2.视图对用户可见     */    private void isCanLoadData() {        if (!isInit) {            return;        }        if (getUserVisibleHint() && !isLoad) {            lazyLoad();            isLoad = true;        } else {            if (isLoad) {                stopLoad();            }        }    }    /**     * layout xml文件ID     *     * @return     */    protected abstract int getLayoutId();    /**     * 控件初始化     */    protected void initView() {    }    @Override    public void onDestroyView() {        if (bind != null) {            bind.unbind();        }        super.onDestroyView();        isInit = false;        isLoad = false;    }    /**     * 当视图初始化并且对用户可见的时候去真正的加载数据     */    protected abstract void lazyLoad() {    }    ;    /**     * 当视图已经对用户不可见并且加载过数据,如果需要在切换到其他页面时停止加载数据,可以覆写此方法     */    protected void stopLoad() {    }}

以上为我解决Fragment空白,各种无法显示的办法,这里感谢http://blog.csdn.net/u011192530/article/details/53235862 ,详细请参考此博客;

原创粉丝点击