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

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"><TextViewandroid: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@Overridepublic 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;}@Overridepublic void onViewCreated(View view, @Nullable Bundle savedInstanceState) {super.onViewCreated(view, savedInstanceState);mContentTv.setText("TestFragment" + mIndex);}@Overridepublic void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);mIndex = getArguments().getInt("index");//根据不同的额index显示不同的内容}@Overridepublic void onStart() {super.onStart();Log.d(TAG,"onStart()" + mIndex);}@Overridepublic void onPause() {super.onPause();Log.d(TAG,"onPause()" + mIndex);}@Overridepublic 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;}@Overridepublic Fragment getItem(int position) {TestFragment testFragment = new TestFragment();Bundle bundle = new Bundle();bundle.putInt("index",position);//传入不同的indextestFragment.setArguments(bundle);return testFragment;}@Overridepublic Object instantiateItem(ViewGroup container, int position) {return super.instantiateItem(container, position);}@Overridepublic int getCount() {return FRAGMENT_COUNT;}//设置Tab的标题@Overridepublic CharSequence getPageTitle(int position) {return mTabTitles.get(position);}}

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

   <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:orientation="vertical"xmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/activity_main"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.example.why.demo.MainActivity"><android.support.design.widget.TabLayoutandroid:id="@+id/tab_layout"android:layout_width="match_parent"android:layout_height="wrap_content"app:tabIndicatorColor="@color/colorAccent"app:tabIndicatorHeight="2dp"app:tabMode="fixed"></android.support.design.widget.TabLayout><android.support.v4.view.ViewPagerandroid:id="@+id/view_pager"android:layout_width="match_parent"android:layout_height="wrap_content"></android.support.v4.view.ViewPager>
</LinearLayout>
TabLayout的属性app:tabMode还有一直模式scrollable,可以自行尝试。代码部分:
public class MainActivity extends AppCompatActivity {@BindView(R.id.tab_layout)TabLayout mTabLayout;@BindView(R.id.view_pager)ViewPager mViewPager;private List<String> mTabTitles = new ArrayList<>();private List<BaseFragment> mFragments = new ArrayList<>();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ButterKnife.bind(this);initTab();mViewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager(),mFragments,mTabTitles));mTabLayout.setupWithViewPager(mViewPager);//注意:这行代码不能少,使TabLayout和ViewPager绑定}//设置Tab的titleprivate void initTab() {for (int i = 0; i < 6; i++) {mTabTitles.add("Tab" + i);}}
}

  这里的代码就只是将ViewPager和TabLayout结合,并设置了Adapter。到这里效果就出来了,当然这里没有对TabLayout的讲解,TabLayout出来也挺久了,除了官网的介绍外,也有很多博客对其进行了讲解,这里也就不介绍了。

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);//传入不同的indextestFragment.setArguments(bundle);return testFragment;
}@Override
public Object instantiateItem(ViewGroup container, int position) {mFragmentTags.add(makeFragmentName(container.getId(),position));//设置tagreturn 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();}}

}

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

ViewPager,TabLayout,Fragment实现tabs滑动相关推荐

  1. android滑动fragment,android中ViewPager结合Fragment进行无限滑动

    实现ViewPager结合Fragment实现无限循环切换,这里也是在适配器里面进行的,当然使用滑动监听也能够实现 import android.support.v4.app.Fragment; im ...

  2. android Viewpager+TabLayout+Fragment遇到的问题记录

    1.使用官方的TabLayout的时候遇到了一些问题,现在记录一下. 问题一: 底部下划线的宽度修改,官方是没有这个方法可以修改下划线的宽度的,只能使用反射来解决这个问题了. 解决方案如下,调用此方法 ...

  3. ViewPager+TabLayout+Fragment刷新Fragment中的数据

    1.ViewPager与TabLayout的初始化: 1 private void initData() { 2 mTabFragmentAdapter = new TabFragmentFirstA ...

  4. ViewPager + TabLayout + Fragment + MediaPlayer的使用

    效果图 在gradle里导包  implementation 'com.android.support:design:28.0.0' activity_main <?xml version=&q ...

  5. TabLayout+Fragment+ViewPager+FragmentStatePagerAdapter实现Tab标签

    首先来看下实现的效果吧: 最近在项目中实现这个效果的时候.尽管自己磕磕绊绊的实现了,可是知识确实模模糊糊的,今天天气异常的冷,在加上这个知识不太熟练,实在是没有心情进行接下来的计划,干脆借着这个时间, ...

  6. Android自定义控件之RecyclerView打造万能ViewPager TabLayout(仿今日头条Tab滑动、Tab多布局、indicator蠕动、自定义indicator、文字颜色渐变)

    文章目录 GitHub:https://github.com/AnJiaoDe/TabLayoutNiubility 该轮子特异功能如下: 使用方法 注意:该轮子适用于androidx中的ViewPa ...

  7. SwipeRefreshLayout+CoordinatorLayout+AppBarLayout+TabLayout+ViewPager+RecyclerView 刷新,不能滑动等问题

    使用SwipeRefreshLayout+CoordinatorLayout+AppBarLayout+TabLayout+ViewPager+Fragment+RecyclerView 实现首页悬浮 ...

  8. Android ViewPager和Fragment实现顶部导航界面滑动效果

    在项目中,我们常常需要实现界面滑动切换的效果.例如,微信界面的左右滑动切换效果.那这种效果是怎么实现的?今天我就带大家简单了解ViewPager,并通过实例来实现该效果. 一. ViewPager 官 ...

  9. Android开发之ViewPager+ActionBar+Fragment实现响应式可滑动Tab

    今天我们要实现的这个效果呢,在Android的应用中十分地常见,我们可以看到下面两张图,无论是系统内置的联系人应用,还是AnyView的阅读器应用,我们总能找到这样的影子,当我们滑动屏幕时,Tab可以 ...

最新文章

  1. 例题6-2 铁轨(Rails, ACM/ICPC CERC 1997, UVa 514)
  2. 第八章 软件项目质量计划
  3. OSM OpenStreetMap 获取城市路网数据及转为ESRI shp数据的方法
  4. 如何修复 Flutter 中的“正在检查 Dart SDK 版本... << 此时出乎意料”错误?
  5. 重磅!四部委发文,以后买房可以省几十万元!
  6. Nginx应用案例分享:压力测试
  7. HDU 4404 Worms(多边形和圆相交)
  8. 9.卷2(进程间通信)---记录上锁
  9. 围棋AI kataGo下载
  10. 树莓派能跑matlab,Matlab树莓派硬件支持平台的搭建
  11. uni-app 小程序跳转微信小程序及APP端(安卓/ios)
  12. uniapp实现身份证实名认证
  13. 详解区块链(很详很长)
  14. 没有粉丝能开快手小店吗?做好有何技巧?
  15. 深度学习之图像分类(九)--ResNeXt 网络结构
  16. Origin绘图后导出图片的方法
  17. 第83节:Java中的学生管理系统分页功能
  18. Liquibase 使用(全)
  19. C# 判断网络是否ping通
  20. 药品名自动归类机器人

热门文章

  1. php循环不出数据,在thinkphp模板中循环数组没有循环出所需要的数据
  2. import cycle not allowed_Cycle药物介绍醋酸群勃龙(2)
  3. SET NOCOUNT ON 作用
  4. arcsde安装步骤_ArcGIS 9.3 安装之 SDE的安装及使用
  5. 关于python语言的浮点数类型_Python 浮点数数据类型详解(float)[学习 Python 必备基础知识][看此一篇就够了]...
  6. 在FFT分析在而立之年的展望与总结
  7. 第十五届全国大学生智能车竞赛车模技术检查表格
  8. 第十五届全国大学生智能汽车竞赛人工智能创意赛
  9. android 自定义span_Android – 为ClickSpan设置自定义可绘制背景
  10. python数据趋势算法_Python数据拟合与广义线性回归算法学习