ViewPager,TabLayout,Fragment实现tabs滑动

来源:互联网 发布:微信公众号助手 源码 编辑:程序博客网 时间:2024/05/18 02:50

ViewPager,TabLayout,Fragment实现tabs滑动

 准备在新的一年开始写点博客,记录自己的成长,如果能给别人一些参考就更好了。

Demo实现:

  前段时间公司的项目遇到了使用 ViewPager,TabLayoutFragment实现一个多个tab之间的滑动,这样的效果在大部分的app中都有,因为有了5.0以后的TabLayout控件,实现这样的效果简单多了。下面是demo的效果图:
  这里写图片描述

接下来就是代码了,先是Fragenmnt的xml文件:

 <?xml version="1.0" encoding="utf-8"?>    <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"        android:orientation="vertical"        android:gravity="center"        android:layout_width="match_parent"        android:layout_height="match_parent">        <TextView            android:gravity="center"            android:id="@+id/tv_content"            android:layout_width="match_parent"            android:layout_height="match_parent"            android:text="hello world"            />    </LinearLayout>

为了简单就写了个TextView,然后是Fragment的代码:

 public class TestFragment extends Fragment {        private static final String TAG ="TestFragment";        private  int mIndex;        @BindView(R.id.tv_content)        TextView mContentTv;        private View mTestView;        public TestFragment(){}        @Nullable        @Override        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {            mTestView = inflater.inflate(R.layout.fragment_test, container, false);            ButterKnife.bind(this, mTestView);            return mTestView;        }        @Override        public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {            super.onViewCreated(view, savedInstanceState);            mContentTv.setText("TestFragment" + mIndex);        }        @Override        public void onCreate(@Nullable Bundle savedInstanceState) {            super.onCreate(savedInstanceState);            mIndex = getArguments().getInt("index");//根据不同的额index显示不同的内容        }        @Override        public void onStart() {            super.onStart();            Log.d(TAG,"onStart()" + mIndex);        }        @Override        public void onPause() {            super.onPause();            Log.d(TAG,"onPause()" + mIndex);        }        @Override        public void onResume() {            super.onResume();            Log.d(TAG,"onResume()" + mIndex);        }    }

那几个生命周期方法是为了待会在Tab之间切换时跟踪一下Fragment的生命周期方法。代码里为了偷懒使用了butterknife插件=_=
  然后是Adapter的代码:

public class ViewPagerAdapter extends FragmentPagerAdapter {        private List<String> mTabTitles ;        private static final int FRAGMENT_COUNT = 6;        public ViewPagerAdapter(FragmentManager fragmentManager, List<BaseFragment> fragments,List<String> tabTitles) {            super(fragmentManager);            mTabTitles = tabTitles;        }        @Override        public Fragment getItem(int position) {            TestFragment testFragment = new TestFragment();            Bundle bundle = new Bundle();            bundle.putInt("index",position);//传入不同的index            testFragment.setArguments(bundle);            return testFragment;        }        @Override        public Object instantiateItem(ViewGroup container, int position) {            return super.instantiateItem(container, position);        }        @Override        public int getCount() {            return FRAGMENT_COUNT;        }        //设置Tab的标题        @Override        public CharSequence getPageTitle(int position) {            return mTabTitles.get(position);        }    }

  好像也没什么注释的,接下来就是Activity的代码了,把这些组合起来使用:

Fragment生命周期跟踪:

  写到这里效果是有了,但是由于ViewPager的预加载机制,导致我当时想实现几个页面同步更新同步(就是几个tab用相同的内容,比如在tab1删除了一些内容,希望在tab2也发生改变了,由于预加载的原因Fragment主要生命周期的方法不会再调用了所以无法在Fragment的生存周期方法中实现改变)更新内容时遇到了点麻烦。先说下ViewPager预加载,每次加载三个,比如现在是ta2那么ta1和tab3也被加载了(当然也可以取消预加载),比如我在Acivity通过mViewPager.setCurrentItem(3),demo初始界面:
  这里写图片描述

  日志:这里写图片描述
  
  可以看到tab2,tab3,tab4的生命周期都被调用了。如果我们从左往右滑动,日志如下:
  这里写图片描述
  现在在tab4,tab2调用了onPause(),tab5被加载了,tab3已经加载过了。如果我们一开始是从右往左滑动,那么日志如下:
  这里写图片描述
  现在在tab2,tab4调用了onPause(),tab1被加载了。

不同Tab的同步更新:

  回到前面的问题,如何同步更新不同tab的内容?在网上找到了一个方法,已经找不到到那篇csdn博客了,表示感谢,解决了我的问题。
  那篇博客里的解决方法是给每个fragment打上tag,使用是FragmentPagerAdapter内部的 String makeFragmentName(int viewId, long id)方法,这里我们可以直接复制放在自己定义的ViewPagerAdapter里给fragment打tag,这个动作放在instantiateItem(ViewGroup container, int position)中,然后要同步更新的时候调用FragmentManager.findFragmentByTag()获取对应的Fragment就可以调用相应的方法了,这里是打上tag后的代码:
  

public class ViewPagerAdapter extends FragmentPagerAdapter {    private List<String> mTabTitles ;    private static final int FRAGMENT_COUNT = 6;    private List<String> mFragmentTags = new ArrayList<>();    private FragmentManager mFragmentManager;    public ViewPagerAdapter(FragmentManager fragmentManager, List<BaseFragment> fragments,List<String> tabTitles) {        super(fragmentManager);        mTabTitles = tabTitles;        this.mFragmentManager = fragmentManager;    }    @Override    public Fragment getItem(int position) {        TestFragment testFragment = new TestFragment();        Bundle bundle = new Bundle();        bundle.putInt("index",position);//传入不同的index        testFragment.setArguments(bundle);        return testFragment;    }    @Override    public Object instantiateItem(ViewGroup container, int position) {        mFragmentTags.add(makeFragmentName(container.getId(),position));//设置tag        return super.instantiateItem(container, position);    }    @Override    public int getCount() {        return FRAGMENT_COUNT;    }    //设置Tab的标题    @Override    public CharSequence getPageTitle(int position) {        return mTabTitles.get(position);    }    //这个方法是FragmentPagerAdapter内部方法,其内部就是根据这个给fragment打tag的,我们直接使用可以获取正确的tag。    private static String makeFragmentName(int viewId, long id) {        return "android:switcher:" + viewId + ":" + id;    }    //这个方法可以在Fragment的代码中调用    public void synchronizedFragment() {        for (int i = 0; i < mFragmentTags.size();i++) {            TestFragment testFragment = (TestFragment) mFragmentManager.findFragmentByTag(mFragmentTags.get(i));            //接下来就可以调用testFragment相应的更新方法了            testFragment.update();        }    }}

就这些了,有些内容参考过别人的文章就不一一贴出来了(很久以前看的),很多内容网上都有,这里只是做个总结。

1 0
原创粉丝点击